Question

Existe-t-il un moyen de collecter (par ex.dans une liste) plusieurs objets « génériques » qui ne partagent pas une super classe commune ?Si oui, comment puis-je accéder à leurs propriétés communes ?

Par exemple:

class MyObject<T>
{
   public T Value { get; set; }
   public string Name { get; set; }

   public MyObject(string name, T value)
   {
      Name = name;
      Value = value;
   }
}

var fst = new MyObject<int>("fst", 42);
var snd = new MyObject<bool>("snd", true);

List<MyObject<?>> list = new List<MyObject<?>>(){fst, snd};

foreach (MyObject<?> o in list)
   Console.WriteLine(o.Name);

Évidemment, c'est du pseudo code, ça ne marche pas.

De plus, je n'ai pas besoin d'accéder à la propriété .Value (car cela ne serait pas sécurisé).

MODIFIER: Maintenant que j'y réfléchis, il serait possible d'utiliser des sous-classes pour cela.Cependant, je pense que cela signifierait que je devrais écrire une nouvelle sous-classe pour chaque nouveau type.


@GrzenioOui, cela répond exactement à ma question.Bien sûr, je dois maintenant dupliquer toute l’interface partagée, mais ce n’est pas un gros problème.J'aurais dû penser à cela...

@akuVous avez raison à propos de la frappe du canard.Je ne m'attendrais pas à ce que deux types d'objets complètement aléatoires soient accessibles.

Mais je pensais que les objets génériques partageraient une sorte d’interface commune, puisqu’ils sont exactement les mêmes, mis à part le type par lequel ils sont paramétrés.Apparemment, ce n’est pas automatiquement le cas.

Était-ce utile?

La solution

Je ne pense pas que ce soit possible en C#, car MyObject n'est pas une classe de base de MyObject.Ce que je fais habituellement, c'est définir une interface (une interface « normale », non générique) et faire en sorte que MyObject implémente cette interface, par exemple.

interface INamedObject
{
    string Name {get;}
}

et ensuite vous pouvez utiliser l'interface :

List<INamedObject> list = new List<INamedObject>(){fst, snd};

foreach (INamedObject o in list)
   Console.WriteLine(o.Name);

Est-ce que cela a répondu à votre question ?

Autres conseils

C# ne prend pas en charge la saisie en canard.Vous avez 2 choix :interfaces et héritage, sinon vous ne pouvez pas accéder aux propriétés similaires de différents types d'objets.

La meilleure façon serait d'ajouter une classe de base commune, sinon vous pouvez vous rabattre sur la réflexion.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top