2016-02-25 3 views
0

У меня есть некоторые трудности с этим. У меня есть абстрактный класс, и я бы хотел добавить публичный абстрактный метод для своих наследников. Проблема заключается в том, что метод должен возвращать общий список классов, реализующих совершенно другой абстрактный класс (NotifyingDatabaseObject).Аннотация Класс - Как указать возврат общего списка

Я хотел бы сделать что-то вроде следующего, но он не будет компилироваться:

public abstract IList<T> GetList(int? id) where T : NotifyingDatabaseObject; 

И, конечно, если я заменю «Т» с «NotifyingDatabaseObject», это потребует наследование классы, чтобы вернуть этот абстрактный класс вместо конкретных.

Любое направление, как я могу это сделать?

Спасибо!

ответ

2

Я предполагаю, что вы хотите, чтобы каждый подкласс вашего базового класса возвращал конкретный подтип NotifyingDatabaseObject. В этом случае необходимо добавить параметр типа к базовому классу и имеют каждый подтип указать, какой подтип NotifyingDatabaseObject они возвращаются:

public abstract class MyAbstractClass<T> 
    where T : NotifyingDatabaseObject 
{ 
    public abstract IList<T> GetList(int? id) ; 
} 

public class MyConcreteClass : MyAbstractClass<NotifyingDatabaseObjectChildClass> 
{ 
    public override IList<NotifyingDatabaseObjectChildClass> GetList(int? id) 
    { 
     return new List<NotifyingDatabaseObjectChildClass>(); 
    } 
} 

Обратите внимание на существующий ответ не делает этого - он требует, чтобы каждый подтипа для поддержки возвращения списка от любой подтип NotifyingDatabaseObject, а не только один в частности. В этом случае единственной возможной реализацией является возврат пустого списка (или null, или исключение, или цикл бесконечно), поскольку классы реализации не имеют общего способа построения значения типа T.

+0

Вы правы - ему нужно вернуть определенный подтип. Позвольте мне взглянуть на это, и я буду изменять вещи по мере необходимости. Благодаря! – DPH

3

Если возвращение типа не имеет никакого отношения к реферату или определенному классу, вы можете использовать параметр типа по методе, как:

public abstract IList<T> GetList<T>(int? id) where T : NotifyingDatabaseObject; 

Конкретный класс будет что-то вроде:

class MyConcreteClass : MyAbstractClass 
{ 
    public override IList<NotifyingDatabaseObjectChildClass> GetList<NotifyingDatabaseObjectChild>(int? id) 
    { 
     return new List<NotifyingDatabaseObjectChildClass>(); 
    } 
} 
+0

Это не скомпилируется. – Lee

+0

Скомпилировано и протестировано! ;) Единственный недостаток - снова передать тип при вызове метода: var mylist = concrete.GetList (10); 'Это потому, что он не может вывести тип из использования. –

+0

Спасибо, это работает очень хорошо! Мне придется бежать назад и снова прочитать руководство по генерикам. – DPH