2009-09-26 6 views
8

Ainsi, plusieurs fois nous avons une fonction qui accepte un IEnumerable ou ICollection en tant que paramètre. Dans les cas où nous avons des éléments simples, mais pas de collection pour les tenir, il faut créer une collection avant de les transmettre à la fonction, comme:Quelle est la manière la plus simple et la plus compacte de créer un IEnumerable <T> ou ICollection <T>?

T o1, o2, o3; 
Foo(new T[] { o1, o2, o3 }); 

J'ai toujours créé un tableau ou une liste, comme je J'ai fait dans le dernier exemple. Mais je me demande, existe-t-il un moyen plus élégant de créer le IEnumerable ou ICollection requis?

Il serait assez cool, si l'on pouvait faire:

Foo({ o1, o2, o3 }); 

Et le compilateur créerait la plus abstraite collection possible qui satisferait aux besoins de IEnumerable ou ICollection (selon lequel la fonction accepte).

De toute façon, comment passerait-on o1, o2 et o3 à un paramètre IEnumerable ou ICollection?

Répondre

10

La version actuelle de C# (3) prend en charge une notation sans type explicite, à savoir

Foo(new [] { o1, o2, o3 }) 

pour créer un tableau. Il y a aussi le Enumerable.Range de Linq pour créer une gamme continue de nombres. Tout le reste doit être mis en œuvre. Dans l'esprit de Java:

public static IEnumerable<T> AsList<T>(params T[] values) { 
    return values; 
} 

à être appelé comme ceci:

Foo(Enumerable.AsList(o1, o2, o3)); 
+1

Je propose que 'asList()' est pas un bon nom pour une méthode qui retourne un 'Enumerable', pas' list'! Que diriez-vous de 'Enumerable.Create'? –

2

En supposant Foo attend un <T> IEnumerable, vous pouvez profiter de l'inférence de type et à faire:

T o1, o2, o3; 
Foo(new []{o1, o2, o3}); 
3

Parfois, j'ai utilisé une méthode avec un argument "params".

Foo(params T[] ts) 

Et si je suis mort sur IEnumerable ensemble je viens de ce délégué de méthode pour celui qui veut IEnumerable.

Foo(params T[] ts) { Foo(ts.AsEnumerable()); } 

Vous devez appeler AsEnumerable ou vous allez recurse.

2

Créer un tableau et le passer est probablement le moyen le plus simple/le plus élégant d'accomplir cela dans la version actuelle de C#. Vous pouvez profiter de la saisie du tableau implicite (c.-à-new[] { ... }, mais c'est aussi loin qu'il se

Je suppose que vous êtes vraiment pour le C# équivalent de cette F syntaxe #:.

let foo = seq [ o1; o2; o3 ] 

qui génère un IEnumerable<T> qui va itérer sur les éléments spécifiés. ('Seq' est en réalité l'alias F # pour 'IEnumerable`, bien que F # ait un support intégré pour eux.)

Malheureusement, puisque c'est une notion largement fonctionnelle, pas d'équivalent C# - mais qui sait quand il sera ajouté, car C# devient de plus en plus amusant ctional.

0

Si vous avez une méthode qui prend un tableau comme dernier paramètre, il peut être judicieux de marquer ce paramètre params. Cela vous permet d'appeler la méthode comme ceci:

Foo(o1, o2, o3); 

Je trouve cela particulièrement utile lors de l'écriture d'un test unitaire pour Foo(), parce que souvent dans une unité de tester mes paramètres sont séparés comme celui-ci, au lieu d'un tableau.

Je déconseille de le faire s'il y a une surcharge de Foo() qui ne prend pas un tableau dans cette position, car il peut être déroutant rapidement.

Je ne veux que le langage C# a permis params pour IList<T>:

void Foo(params IList<T> ts) { ... } 
Questions connexes