Pourquoi ne puis-je pas utiliser un IEnumerable avec params? Cela changera-t-il à l'avenir?
Réponses
Trop de publicités?Pourquoi ne puis-je pas utiliser un IEnumerable avec params?
Pour qu'une fonction soit utilisée par vous, il doit être pensé, conçu, a précisé, mise en œuvre, testé, documenté et expédiés.
Le "params énumérable" a été pensé et conçu. Il n'a jamais été spécifié, mise en œuvre, testé, documenté ou expédiés.
Par conséquent, vous ne pouvez pas utiliser la fonction.
Mise à JOUR: je me dois de préciser ce que j'entends par "la fonction" puisque c'est possible, nous avons tous des idées différentes dans nos têtes que "la fonctionnalité" est. La fonctionnalité que je suis en train de parler de vous permettre de dire quelque chose comme
void Frob(params IEnumerable<int> x) { foreach(int y in x) ... }
et puis le site d'appel peut être soit dans la "forme normale" de passer d'une séquence d'entiers, ou de la "forme élargie" de Frob(10, 20, 30). Si dans la forme développée, le compilateur génère l'appel comme si vous avais dit Frob(new int[] { 10, 20, 30}), de la même façon que pour les param tableaux. Le point de la caractéristique est qu'il est souvent le cas que la méthode n'utilise jamais l'accès aléatoire à la matrice, et par conséquent, on pourrait affaiblir l'exigence que les params être un tableau. Les params pourrait être simplement une séquence à la place.
Vous pouvez le faire aujourd'hui en faisant une surcharge:
void Frob(params int[] x) { Frob((IEnumerable<int>)x); } void Frob(IEnumerable<int> x) { foreach(int y in x) ... }
ce qui est un peu de douleur. Nous pourrions tout simplement vous permettre d'utiliser IEnumerable comme le type de la params argument et être fait avec elle.
Sera-ce jamais être corrigé?
Je l'espère. Cette fonctionnalité a été sur la liste pendant une longue période. Il ferait beaucoup de fonctions de travail beaucoup plus parfaitement avec LINQ.
Frob(from c in customers select c.Age);
sans avoir à écrire deux versions différentes de Frob.
Cependant, il est un simple "petit confort" caractéristique; il ne fait pas ajouter tout un tas de nouveau pouvoir de la langue. C'est pourquoi il n'est jamais assez haut sur la liste de priorité pour se rendre à la "spécification est écrit" la scène.
Je souhaite vraiment que de la réécrire les anciennes bibliothèques à l'utilisation des génériques.
Commentaire noté.
Ah, je pense que je peut maintenant avoir compris ce que tu veux dire. Je pense que vous voulez être en mesure de déclarer une méthode comme ceci:
public void Foo<T>(params IEnumerable<T> items)
{
}
Et ensuite être capable de l'appeler avec un "normal" argument comme ceci:
IEnumerable<string> existingEnumerable = ...;
Foo(existingEnumerable);
ou avec plusieurs paramètres comme ceci:
Foo("first", "second", "third");
Est-ce que vous êtes après? (À noter que vous voudriez la première forme d'utilisation T=string
, plutôt que d' T=IEnumerable<string>
avec un seul élément...)
Si oui, je suis d'accord, il pourrait être utile - mais il est assez facile d'avoir:
public void Foo<T>(params T[] items)
{
Foo((IEnumerable<T>) items);
}
public void Foo<T>(IEnumerable<T> items)
{
}
Je ne trouve pas que je le fais assez souvent pour faire le dessus d'une particulièrement laid solution de contournement.
Notez que lors de l'appel le code ci-dessus, vous devrez explicitement spécifier le type d'argument, pour éviter que le compilateur préférant l' params
exemple. Ainsi, par exemple:
List<string> x = new List<string>();
Foo<string>(x);
Selon la fonctionnalité du langage état de la mise en page de la Roslyn projet, ce qui est prévu pour être mis en œuvre dans les prochaines versions de C# (probablement en C# 6.0).
Donc, vous n'avez plus besoin de définir vos paramètres de méthodes comme un tableau et en vigueur au début de l'évaluation des arguments:
Avant
Do(values.ToArray());
...
public void Do(params int[] values) { ... }
Après
Do(values);
public void Do(params IEnumerable<Point> points) { ... }