2013-05-03 4 views
2

У меня очень простой вопрос, но раньше у меня не было этой проблемы.Интерфейс, ссылающийся на другой интерфейс, но класс, ссылающийся на другой класс в C#

Посмотрите на этот код:

interface IFoo 
{ 
    IBar MyBar { get; } 
} 

interface IBar 
{ 
    String Test { get; } 
} 

class Foo : IFoo 
{ 
    public Bar MyBar { get; set; } 
} 

class Bar : IBar 
{ 
    public String Test { get; set; } 
} 

Проблема заключается в том, что Foo не реализует IFoo, поскольку она возвращает панель, а не IBar. Но я не вижу проблемы, поскольку Bar реализует IBar. Я что-то пропустил?

Я хочу, чтобы мое приложение использовало класс Foo, но выставлять IFoo для других частей решения.

Это путь вокруг него, но мне кажется, как уродливое решение:

class Foo : IFoo 
{ 
    public Bar MyBar { get; set; } 
    IBar IFoo.MyBar { 
     get { return this.MyBar; } 
    } 
} 

Является ли это путь, или это может быть лучше?

+1

'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''. –

+0

Это называется ковариацией возвращаемого типа и согласно [этому сообщению] (http://stackoverflow.com/questions/5709034/does-c-sharp-support-return-type-covariance) C# и CLR не поддерживает его , – Dirk

+3

«Уродливый путь» (также известный как явная реализация интерфейса) действительно является единственным способом решения этой проблемы на C#. Фактически, это часть причины, по которой функция существует в первую очередь. – dasblinkenlight

ответ

2

Вы можете сделать это:

interface IFoo<out B> where B:IBar 
{ 
    B MyBar { get; } 
} 

interface IBar 
{ 
    String Test { get; } 
} 

class Foo : IFoo<Bar> 
{ 
    public Bar MyBar { get; set; } 
} 

class Bar : IBar 
{ 
    public String Test { get; set; } 
} 

Это будет работать только в том случае, B в выходном положении (по понятным причинам, если вы думаете об этом достаточно долго).

-1

Проблема в том, что Foo не реализует IFoo, поскольку он возвращает Bar, а не IBar. Но я не вижу проблемы, поскольку Bar реализует IBar. Я что-то пропустил?

Да. Вы неверно истолковываете контракт интерфейса IFoo. Контракт прост:

Одно из объектов с именем MyBar, у которого есть геттер, и имеет тип возврата IBar. Контракт не в том, что он возвращает объект, который имеет тип IBar, а тип возврата - тип IBar.

Это стандарт. Попробуйте реализовать интерфейс ICloneable, который имеет один метод, Clone(), с обратным типом object. Реализация этого интерфейса означает, что вы должны реализовать метод с возвращаемым типом object, независимо от того, что. Даже если вы предпочитаете быть более конкретным, любой другой тип возврата не будет квалифицироваться.

Способом, который вы предложили, является одним из правильных способов обойти это - иметь свойство IBar, которое возвращает свойство Bar. Или, знаешь, у тебя может просто иметь свойство IBar и установить его в экземпляр Bar, так как это совершенно верно, а затем работать с вашим объектом IBar через контракт IBar. Это поможет с развязкой.

Смежные вопросы