Рассмотрим иерархию классов, которая выглядит как показано ниже. В сущности, есть аннотация ComplexBase
с некоторыми полями, которые являются общими для всех классов. Затем есть ComplexClass
, полученный от ComplexBase
, который, помимо прочего, содержит коллекцию ComplexElement
s, также полученную от ComplexBase
.Ковариация для классов со списком в C#
public abstract class ComplexBase {
internal abstract string Identifier { get; }
}
public abstract class ComplexClass<T> : ComplexBase where T : ComplexElement {
internal SortedList<string, T> Elements { get; set; }
}
public abstract class ComplexElement : ComplexBase { }
Реализации абстрактных классов ComplexClassA
и ComplexClassB
. В коллекции только ComplexElement
содержатся только экземпляры ComplexElementA
, а только последние ComplexElementB
.
public class ComplexClassA : ComplexClass<ComplexElementA> {
public ComplexClassA() {
Elements = new SortedList<string, ComplexElementA>();
}
}
public class ComplexElementA : ComplexElement { }
public class ComplexClassB : ComplexClass<ComplexElementB> {
public ComplexClassB() {
Elements = new SortedList<string, ComplexElementB>();
}
}
public class ComplexElementB : ComplexElement { }
То, что я изо всех сил, чтобы понять, как определить новый класс TheBigCollection
, занимающих различные поля и методы, плюс набор экземпляров обоих ComplexClassA
и ComplexClassB
. Нерабочая версия может выглядеть
public class TheBigCollection {
internal SortedList<string, ComplexClass> Classes { get; set; }
public TheBigCollection() {
Classes = new SortedList<string, ComplexClass>();
}
public void Add(string name, ComplexClass element) {
Classes.Add(name, element);
}
}
Конечно, это не компилируется, так как ComplexClass
определяются с общим типом.
Моего previous attempt был использовать концепцию сокрытия списков, но оказывается, что это мешает мне получить доступ списков ComplexElements
в случаях ComplexClassA
или ComplexClassB
что я извлекаемые из списка в TheBigCollection
.
Я узнал из своего предыдущего сообщения, что ковариация может решить проблему, но я не понимаю, как использование IEnumerable
, которое является неизменным, может использоваться для добавления новых элементов tho TheBigCollection
в список классов.
Считаете ли вы создание промежуточного класса ComplexClassBase: ComplexBase и наследование ComplexClass из ComplexClassBase? –
michauzo
@michauzo Да, я сделал очень многое в ответ на [этот пост] (http://www.gamedev.net/topic/660308-list-of-generic-objects/). Проблема, возникающая в связи с этим решением, заключается в том, что я не могу перебирать список «Классы» и, к примеру, получить доступ к элементу «Элементы.Count» каждого элемента без надлежащего приведения. – Informagic
в промежуточном классе (или интерфейсе) вы можете поместить свойство SortedList Elements {get; задавать; }, а затем реализовать его в ComplexClass с использованием специализированного типа. –
michauzo