Covariance avec C #

J’ai rencontré un problème de covariance intéressant dans mon code c #.

J’ai une classe générique Masortingx et elle a été instanciée, par exemple Masortingx , Masortingx et Masortingx .

Pour ma logique métier, je les ai emballés dans un Wrapper générique Wrapper . Cet INonGenericWrapper interface INonGenericWrapper non générique. Donc, j’ai Wrapper , Wrapper et Wrapper .

Mon problème est: je voudrais définir un conteneur pour tous ces 3 Wrapper s. Je ne peux pas dire List<Wrapper> , car je ne peux pas insérer Wrapper dans cette collection. Je ne peux même pas dire List , car dans mon foreach, je voudrais accéder au paramètre générique Masortingx .

Partie Cheesy: ces wrappers seront (dés) sérialisés avec le type défini: MySerializer<Wrapper>.Serialize(_myInstanceOfWrappedApple) .

Je pense qu’il est clair que je voudrais éviter d’énormes commutations de typeof lors de la sérialisation ..

Quelles sont mes solutions de contournement possibles? Je suis un peu coincé.

Merci d’avance,

Récemment, j’ai rencontré une telle limitation et j’ai implémenté une variante de Visitor Pattern (qui pourrait en abuser). Mais cela m’a aidé à résoudre le problème.

Je ne suis pas un architecte, juste un développeur. Alors pardonnez-moi si j’abuse du motif, mais cela aidera certainement.

Avec les informations fournies, j’ai créé des simulacres de vos classes et appliqué le modèle de visiteur comme suit.

 public class Masortingx { public T Obj { get; set; } } public interface INonGenericWrapper { void Wrap(); void Accept(IVisitor visitor); } public class Wrapper : INonGenericWrapper { public Masortingx Masortingx { get; private set; } public void Wrap() { //Your domain specific method } public void Accept(IVisitor visitor) { visitor.Visit(this); } } public interface IVisitor { void Visit(T element); } public class SerializationVisitor : IVisitor { public void Visit(T element) { new Serializer().Serialize(element); } } public class Serializer { public Stream Serialize(T objectToSerialize) { Console.WriteLine("Serializing {0}", objectToSerialize); //Your serialization logic here return null; } } 

Comment utiliser:

 List wrappers = new List(); wrappers.Add(new Wrapper()); wrappers.Add(new Wrapper()); wrappers.Add(new Wrapper()); var visitor = new SerializationVisitor();//Create the operation you need to apply foreach (var wrapper in wrappers) { wrapper.Accept(visitor); } 

Tout ce que vous avez à faire est de créer un nouveau visiteur pour chaque opération à effectuer.

Voici la démo qui sort

 Serializing Wrapper`1[System.Object] Serializing Wrapper`1[System.Ssortingng] Serializing Wrapper`1[System.Int32] 

Vous avez dit que vous souhaitez pouvoir insérer des données dans la collection en fonction du type exposé de manière covariante. Ce n’est tout simplement pas possible. Pour qu’un type soit covariant, il ne doit exposer aucun moyen d’insérer des données. Le type devrait être contravariant pour supporter cela, mais s’il est contravariant, il ne peut pas afficher les informations dans un manoir covariant.

En bref, cela est impossible, et pas seulement impossible à cause de la mise en œuvre de C # en tant que langage, mais impossible au niveau conceptuel. Il n’est pas possible d’implémenter une solution typée de manière statique à ce problème dans un langage concevable.