Considérons une hiérarchie de classes qui ressemble à ci-dessous. En substance, il y a un résumé ComplexBase
avec des champs communs à toutes les classes. Puis il y a un ComplexClass
dérivé de ComplexBase
qui, entre autres choses, détient une collection de ComplexElement
s également dérivé de ComplexBase
.Covariance pour les classes avec des membres de liste en 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 { }
des classes Implémentations abstraites sont ComplexClassA
et ComplexClassB
. La collection ComplexElement
de la première contient uniquement des instances de ComplexElementA
et de cette dernière seulement 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 { }
Ce que je suis mal à comprendre est comment définir une nouvelle classe TheBigCollection
occupant différents domaines et méthodes, ainsi qu'une collection d'instances des deux ComplexClassA
et ComplexClassB
. Une version non-travail pourrait ressembler à
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);
}
}
Bien sûr, cela ne compile pas depuis ComplexClass
est définie avec un type générique.
Mon previous attempt était d'utiliser un concept de cacher les listes, mais il se trouve que cela me empêche d'accéder aux listes de ComplexElements
dans les cas de ComplexClassA
ou ComplexClassB
que je récupère dans la liste TheBigCollection
.
J'ai appris de mon article précédent que la covariance pouvait résoudre le problème, mais je ne comprends pas comment utiliser IEnumerable
- qui est immuable - peut être utilisé pour ajouter de nouveaux éléments à la liste des classes TheBigCollection
.
Avez-vous envisagé de créer une classe complexe ComplexClassBase: ComplexBase et d'hériter ComplexClass de ComplexClassBase? –
michauzo
@michauzo Oui, je l'ai fait, très bien dans la ligne de la réponse à [ce poste] (http://www.gamedev.net/topic/660308-list-of-generic-objects/). Le problème qui se pose avec cette solution est que je ne peux pas itérer sur la liste 'Classes' et accéder, par exemple, à la propriété' Elements.Count' de chaque élément sans un cast approprié. – Informagic
dans la classe intermédiaire (ou l'interface) vous pouvez mettre la propriété SortedList Elements {get; ensemble; } puis l'implémenter dans ComplexClass en utilisant un type spécialisé. –
michauzo