2
votes

FOR-EACH sur un IEnumerable vs une liste

Y a-t-il un avantage ou une différence si ma boucle for-each passe par l'argument de méthode si je passe cet argument en tant que IEnumerable ou si je passe cet argument en tant que Liste ?

c#

2 commentaires

La différence entre passer des choses en tant que IEnumerable (et, par là, je suppose que IEnumerable ) et List est une méthode qui a un paramètre IEnumerable (ou un appelant qui obtient un IEnumerable comme type de retour) obtient une collection qui ne peut pas être modifiée. Les paramètres List (et les types de retour) permettent aux destinataires de la liste de modifier le contenu de la liste.


@ Flydog57, eh bien une collection peut toujours être modifiée, même lorsqu'elle est passée comme référence IEnumerable , simplement par exemple en faisant quelque chose comme (énumérable comme ICollection ) ?. Clear (); . Je crois que vous vouliez dire qu'une méthode avec un paramètre IEnumerable indique qu'elle ne modifiera aucune collection passée en argument ...


5 Réponses :


5
votes

Dans le cas général, il peut y avoir une différence si la collection a une implémentation d'interface explicite de IEnumerable

List a l'implémentation explicite, mais ne change pas de comportement. Il n'y a aucune différence dans votre cas. Voir: https://referencesource.microsoft.com/#mscorlib/system /collections/generic/list.cs en regardant GetEnumerator et similaire


0 commentaires

0
votes

Si vous passez le même objet, peu importe que votre méthode accepte IEnumerable ou List.

Cependant, si tout ce que vous allez faire à l'intérieur de la méthode est d'énumérer l'objet, il est préférable d'attendre un IEnumerable dans l'argument de la méthode, vous ne voulez pas limiter l'appelant de la méthode en attendant un List. / p>


0 commentaires

7
votes

Si votre IEnumerable est implémenté par List alors non; aucune différence. Il y a cependant une grande différence conceptuelle; le IEnumerable indique "Je peux être énuméré", ce qui signifie également que le nombre d'éléments n'est pas connu et que l'énumération ne peut pas être inversée ou accédée au hasard. La liste dit "Je suis une liste entièrement formée, déjà remplie; je peux être inversée et accédée au hasard".

Vous devez donc généralement construire votre interface de fonction pour accepter la fonctionnalité la plus basse compatible avec votre opération; si vous allez seulement énumérer les avant, de manière itérative, acceptez IEnumerable - cela permet à votre fonction d'être utilisée dans plus de scénarios.

Si vous avez fait accepter à votre fonction uniquement List (), tout appelant avec un tableau ou IEnumerable passé dedans, doit convertir son entrée en List () avant d'appeler votre fonction - ce qui peut bien être moins performant que de simplement passer par leur tableau ou IEnumerable directement. En ce sens, accepter un IEnumerable invite à un meilleur code de performance.


0 commentaires

3
votes

Non, il n'y en a pas. Dans les deux cas, le for-each est traduit en quelque chose comme ceci

var enumerator = input.GetEnumerator();
while(enumerator.MoveNext())
{
    // loop body.
    // The current value is accessed through: enumerator.Current
}

De plus, si l'énumérateur est jetable, il sera éliminé après la boucle.

Jon Skeet donne une description détaillée ici .


2 commentaires

il y a un Dispose () là-dedans aussi, notez


Oui, mais uniquement si l'énumérateur est jetable. (Notez que je l'ai mentionné mais ne l'ai pas inclus dans l'exemple de code,)



0
votes

Non, il n'y a aucun avantage ou différence quant à la façon dont la boucle foreach passerait par la collection. Comme Olivier Jacot-Descombes l'a souligné, la boucle foreach passera simplement par les éléments un par un à l'aide de l'énumérateur.

Cependant, cela peut faire une différence si votre logique passe par la même collection au moins deux fois . Dans ce cas, si IEnumerable<> est utilisé, vous pourriez finir par régénérer les éléments à chaque fois que vous parcourez l'itérateur. ReSharper a même un avertissement spécial pour ce type de code: PossibleMultipleEnumeration Je ne dis pas que vous ne devriez pas utiliser IEnumerable<> . Tout a son temps et son lieu et ce n'est pas toujours une bonne idée d'utiliser l'interface la plus générique. Soyez prudent dans votre choix.


0 commentaires