2013-12-09 3 views
1

Предположим, у нас есть иерархия интерфейсов: IBaseThing<T> и IChildThing:IBase<ChildThing>. Также есть два класса, как это:Наследование интерфейса и абстрактный метод переопределения

internal abstract class Base<T> 
{ 
    public abstract IBaseThing<T> Thing {get;} 
} 

и

internal class Concrete:Base<ChildThing> 
{ 
    public override IChildThing Thing 
    { 
     get 
     { 
      return GetChildThing(); 
     } 
    } 
} 

Что будет происходить в качестве ниже:

'Бетон' не реализует унаследовали абстрактный член «Base. get '

Я хочу пропустить отливку (IChildThing)this.Thing по всему классу Concrete. Что я должен был делать?

+0

'IChildThing: IBase ' - невероятно вонючий интерфейс. Может быть, вы хотели 'ChildThing: IBase ' .. Не могу быть уверенным. – nawfal

+0

Неверное предположение nawfal. IThings не T. –

+0

Реза, пожалуйста, отправьте полный пример (пока только то, что требуется) и прецедент u r после. Мы могли бы помочь вам лучше. Иначе все его предположения. – nawfal

ответ

2

Вы не можете сделать это. Система типов справедливо возражает против того, что вы пытаетесь изменить тип метода в классе переопределения. IChildThing может происходить из IBaseThing, но это не одно и то же. Например, позже вы можете добавить несколько методов в IChildThing. Тогда один класс (Concrete) обещает вернуть объект с другой подписью, чем базовый класс, - это ошибка типа.

Если вам необходимо обратиться к IChildThing в некоторых случаях, как о чем-то вроде:

internal class Concrete : Base<ChildThing> 
{ 
    public override IBaseThing<ChildThing> Thing 
    { 
     get { return ChildThing; } 
    } 

    public IChildThing ChildThing { get; set; } 
} 

Если все у вас есть это база, хотя, то вы не можете получить на IChildThing безопасно. Это характер сильно типизированной системы, подобной этой. Если это проблема, то, если вы дадите более конкретный пример, я могу предложить, как реструктурировать, чтобы избежать этой проблемы.

+0

Я не могу определить, использование 'Thing' сейчас! Я объявляю Thing как свойство доступным из других классов. Внутри это работает, но на самом деле вы проигнорировали философию собственности. правильно? –

+1

Что значит, я проигнорировал «философию собственности»? Я не знаком с тем, что вы имеете в виду. –

+0

Мы указываем свойство для предоставления get и set для других классов, что означает, что частная собственность не является разумной, вместо этого мы можем использовать личное поле. В вашем решении 'IBaseThing Thing' не расходуется, как IChildThing в других классах без кастинга, который не является тем, что я ищу. –

2

Попробуйте это решение:

public interface IBaseThing {} 

public interface IChildThing : IBaseThing {} 

internal abstract class Base<T> where T : IBaseThing 
{ 
    public abstract T Thing {get;} 
} 

internal class Concrete:Base<IChildThing> 
{ 
    public override IChildThing Thing 
    { 
     get 
     { 
      return GetChildThing(); 
     } 
    } 

    public IChildThing GetChildThing() 
    { 
     // Your impelementation here... 
     return null; 
    } 
} 
+0

Скомпилирует? Я не уверен. – nawfal

+2

Разве это не то же самое, что вопрос? –

+0

Это именно то, что я хочу сделать, но у меня ошибка выше. –

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