Params IEnumerable<T> c#
Pourquoi ne puis-je pas utiliser un IEnumerable avec params? Sera-ce jamais être corrigé? Je souhaite vraiment que de la réécrire les anciennes bibliothèques à utiliser des génériques...
- Est-ce un coup de gueule ou une question?
- clairement, c'est les deux. +1 pour la question. Souhaite que je pourrais lui donner une seconde +1 pour le coup de gueule aussi.
- avant la modification, la question ressemblait coup de gueule, mais pour quoi le titre de la question transmet, c'est une très bonne question..
- Restaurée à la question d'origine, principalement parce que la réponse ci-dessous à partir de Eric Lippert - qui était alors un compilateur C# dev - se réfère à la formulation d'origine. Si il ne l'avait pas exception à la formulation, nous avons probablement n'avez pas besoin non plus!
- Légère tatillonne,
params array
est encore générique, rendantIEnumerable
l'habitude d'ajouter à son genericity. Peut-être que vous avez voulu dire la rendre plus générale (but).
Vous devez vous connecter pour publier un commentaire.
La question présuppose que l'équipe de conception doit fournir une raison pour pas ajouter une fonctionnalité à la langue. Ce présupposé est faux.
Plutôt, 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. Toutes ces activités ont des coûts importants.
La "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: cette écriture -- début de l'année 2015, a été spécifié, mais la mise en œuvre, les essais, la documentation et l'expédition ont été coupés pour C# 6.0 dans la dernière partie de 2014. Voir Lucian de l'annonce ici: http://roslyn.codeplex.com/discussions/568820.
Depuis il n'a pas encore été mis en place, testé, documenté et expédié, il n'y a toujours pas de cette fonctionnalité. J'espère que cela va le faire dans un futur hypothétique version de C#.
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
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:
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.
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.
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.
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:
Et ensuite être capable de l'appeler avec un "normal" argument comme ceci:
ou avec plusieurs paramètres comme ceci:
Est-ce que vous êtes après? (À noter que vous voudriez la première forme d'utilisation
T=string
, plutôt que deT=IEnumerable<string>
avec un seul élément...)Si oui, je suis d'accord c' pourrait être utile - mais il est assez facile d'avoir:
Je ne trouve pas que je le fais assez souvent pour faire le dessus d'une particulièrement laid solution de contournement.
Noter que lors de l'appel le code ci-dessus, vous aurez envie de explicitement spécifier le type d'argument, pour éviter que le compilateur préférant la
params
exemple. Ainsi, par exemple:public void Foo<IEnumerable<int>>(params IEnumerable<int>[])
params IEnumerable<int>[]
?Foo<T>(params T[] items)
matchs en premier siT
estIEnumerable<int>
plutôt queFoo<T>(IEnumerable<T> items)
IEnumerable<T>
plutôt queList<T>
ou le compilateur préfère leparams
version. Voir gist.github.com/bradphelan/9fddca0fa5f1c07ba736 pour un fichier exécutable exempleFoo<string>
puis il travaille dans les deux cas. Je vais modifier ma réponse pour que ce soit clair.Les paramètres les paramètres sont envoyés sous forme de tableau, et un
IEnumerable<T>
ne fournit pas l'accès aléatoire qui est requis d'agir comme un tableau.Vous devez créer le tableau à partir de l'interface IEnumerable lorsque vous appelez la méthode:
IEnumerable<T>
interface n'existait pas lors deparams
a été ajouté à la langue. Pourquoi il n'a pas été ajouté par la suite est probablement parce qu'il n'est pas très utile. Vous pouvez simplement ajouter une surcharge de soutenir à la foisparams T[]
etIEnumerable<T>
..ToArray()
-- ce qui est stupide.