2009-04-16 11 views
12

je classe où la partie pertinente ressembleobjet générique à la liste générique en C#

class C { 
    void Method<T>(SomeClass<T> obj) { 
     list.Add(obj); 
    } 
    List<?> list = new List<?>(); 
} 

Comment dois-je définir la liste afin que la classe compile?

Je veux une liste de type List<SomeClass<?>>, c'est-à-dire une liste d'objets de SomeClass où chaque objet peut avoir n'importe quel paramètre de type. La construction Java ? le permet; quel est l'équivalent C#? Si une telle chose n'existe pas, existe-t-il une solution de contournement appropriée? (A List<object> ferait, mais est terriblement laid.)

+0

Pouvez-vous élaborer sur le type d'éléments que vous souhaitez ajouter via la fonction "Méthode"? – el2iot2

+0

ah, je le vois dans un commentaire. – el2iot2

+0

Dans C# 4.0 vous pouvez déclarer SomeClass comme dynamique et ne pas utiliser les génériques. La liste devient ensuite Liste . – Goran

Répondre

13

Je ne vous crois pas que vous pouvez le faire en C# ... doivent ajouter le paramètre de type à la classe:

class C<T> { 
    void Method(SomeClass<T> obj) { 
     list.Add(obj); 
    } 
    List<SomeClass<T>> list = new List<SomeClass<T>>(); 
} 

L'autre option serait d'utiliser une interface:

class C { 

    void Method<T>(T obj) 
     where T : ISomeClass { 
     list.Add(obj); 
    } 
    List<ISomeClass> list = new List<ISomeClass>(); 
} 
+0

Je pense que cela devient plus à l'esprit de ce que je comprends le questionneur à poser (la version de l'interface). Fondamentalement, c'est une liste d'éléments "partiellement connus", mais plus que juste "Liste " – el2iot2

+1

Merci pour l'aide. Donc stackoverflow me permet de modifier ma question ...mais y at-il un moyen de combiner votre réponse avec ceux ci-dessous qui ajoutent des informations supplémentaires sur l'impossibilité de ce que je veux en C#? – errcw

+0

@errcw Je peux l'éditer, ou n'importe quelle autre personne avec 2k + rep peut ... quelles informations spécifiques voulez-vous? –

2

Malheureusement, il n'y a pas d'équivalent direct en C# 3.0 car les génériques sont invariants. Vous serez en mesure de faire quelque chose comme ça d'une manière gracieuse en utilisant C# 4.0 sécurité co/contra-variance caractéristique. Pour contourner ce problème, vous pouvez hériter SomeClass<T> d'une base non générique et créer un List<BaseClass> à la place. Si chaque instance de la classe doit contenir un seul type, vous pouvez rendre la classe elle-même générique et y définir le paramètre de type.

+0

Merci pour l'astuce BaseClass, vraiment utile quand vous voulez émuler des jokers Java. –

4

Pour faire ce que vous voulez, vous avez deux options.

Vous pouvez utiliser la liste <objet> et gérer des objets. Ce ne sera pas de typesafe, et aura des problèmes de boxing/unboxing pour les types de valeur, mais cela fonctionnera.

Votre autre option consiste à utiliser une contrainte générique pour limiter à une classe de base ou une interface et à utiliser une interface < de liste >.

2

Je ne connais rien à la construction ? de Java, mais je pense que ce qui suit préserve le mieux votre syntaxe existante tout en correspondant à votre description.

class SomeClass<T> 
    { 
    } 

    class C 
    { 
     void Add<T>(SomeClass<T> item) 
     { 
      Type type = typeof(SomeClass<T>); 
      if (!list.ContainsKey(type)) 
       list[type] = new List<SomeClass<T>>(); 
      var l = (List<SomeClass<T>>)list[type]; 
      l.Add(item); 
     } 

     public void Method<T>(SomeClass<T> obj) 
     { 
      Add(obj); 
     } 
     readonly Dictionary<Type, object> list = new Dictionary<Type, object>(); 
    } 

essai avec les éléments suivants:

class Program 
    { 
     static void Main(string[] args) 
     { 
      var c = new C(); 
      var sc1 = new SomeClass<int>(); 
      var sc2 = new SomeClass<String>(); 
      c.Method(sc1); 
      c.Method(sc2); 
      c.Method(sc1); 
      c.Method(sc2); 
     } 
    } 
0

Personnellement, je referais ce si possible; déplace le paramètre générique de la méthode vers la classe.

class C<T> { 
    void Method(SomeClass<T> obj) { 
     list.Add(obj); 
    } 
    List<?> list = new List<?>(); 
} 

Si votre liste générique est membre, il va de soi que la classe devrait être construite dans cet esprit. Il est difficile pour nous de suggérer le meilleur modèle sans plus de contexte d'utilisation pour la classe.

Questions connexes