2014-10-21 2 views
0

Предположим, у меня есть общий абстрактный класс:Перечень проведение родовыми-унаследованы классы

ClassA<T> where T: ClassB 

Теперь

public class ClassC: ClassB 

и

public class NewClass: ClassA<ClassC> 

Я могу создать NewClass объект по умолчанию конструктор, но я не могу найти способ удержать его в общем наборе более общих ClassA<T> объектов. Список определяется как

List<ClassA<ClassB>> 

не может держать NewClass объекты. Я бы хотел, чтобы в той же коллекции сохранялись разные типы derrived. Есть ли способ сделать это на C#? Кроме того, я хотел бы избежать использования интерфейсов и виртуальных вызовов, если это возможно.

+1

http://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx –

+3

Почему избежать интерфейсов? Я предпочел бы избегать подклассификации и предпочитаю композицию над наследованием. Http://en.wikipedia.org/wiki/Composition_over_inheritance –

+0

@DennisTraub Я прототипирую игровой движок и вызовы интерфейса слишком дороги для этой цели. – Tarec

ответ

2

Ваша проблема намного проще, чем ваша вещь, она имеет отношение к parameter variance. Посмотреть эти очень простые классы:

public class Base {} 

public class Derived : Base {} 

List<Derived> является неList<Base>, и это именно проблема вы столкнулись. Почему это? Потому что вы можете добавить new Base() к последнему, но не к первому. Аналогичным образом в вашем случае NewClass является ClassA<ClassC>, а ClassC наследует от ClassB, но NewClass является не a ClassA<ClassB>.

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

редактировать: идеи реализации некоторых

Вы можете, например, определить ковариантный интерфейс интерфейса:

public interface IClassA<out T> where T : ClassB 

Тогда List<IClass<ClassB>> сможет провести NewClass

Или вы можете иметь ClassA<T> наследуется от неродственного базового класса ClassA.

public class ClassA 
public class ClassA<T> : ClassA where T : ClassB 

Тогда вы можете хранить ваши NewClass через List<ClassA>

+0

Я знаю об этом, но в f.e. в Java были подстановочные знаки, позволяющие определять подклассы для общих коллекций, и я ищу аналогичное решение в C#. Вы правы в перепроектировании - я сделаю это, если меня не будут использовать. – Tarec

+2

@Tarec Это не безопасный тип на концептуальном уровне. Дело не в том, что C# имеет или не имеет функции. Нельзя безопасно относиться к «списку», как если бы он был ковариантным без удаления статической типизации. – Servy

+0

Благодарим вас обоих, обсуждение немного очищает мою голову, и мне кажется, что я начал с некоторой неправильной концепции в начале. – Tarec