web-dev-qa-db-fra.com

IEnumerable et commander

J'ai une question sur order in IEnumerable.

Pour autant que je sache, l'itération via IEnumerable est un pseudo-code qui peut être écrit de la manière suivante:

while (enumerable.HasNext())
{
    object obj = enumerable.Current;
    ...
}

Supposons maintenant que l'on doive opérer sur une collection triée. Puis-je utiliser IEnumerable dans ce cas ou est-il préférable d'essayer d'autres moyens (c'est-à-dire IList) avec le support d'indexation?

En d'autres termes: le contrat de IEnumerable donne-t-il des garanties sur la commande en général?

Ainsi, IEnumerable n'est pas un moyen approprié pour une interface générique qui garantit la commande. La nouvelle question est de savoir quelle interface ou classe doit être utilisée pour une collection immuable avec ordre? ReadonlyCollection? IList? Les deux contiennent la méthode Add() (même n'est pas implémenté dans la précédente).

Mes propres réflexions: IEnumerable ne donne aucune garantie sur la commande. L'implémentation correcte pourrait renvoyer les mêmes éléments dans un ordre différent dans différentes énumérations (pensez à une requête SQL)

Je connais LINQ First(), mais si IEnumerable ne dit pas un mot sur sa commande, cette extension est assez inutile.

43
undefined

IEnumerable/IEnumerable<T> ne donne aucune garantie quant à la commande, mais les implémentations qui utilisent IEnumerable/IEnumerable<T>peut ou non garantir la commande.

Par exemple, si vous énumérez List<T>, l'ordre est garanti, mais si vous énumérez HashSet<T> aucune garantie n'est fournie, mais les deux seront énumérés à l'aide du IEnumerable<T> interface.

38
spender

Détails de mise en œuvre. IEnumerable énumérera l'élément - la façon dont cela est implémenté dépend de l'implémentation. La plupart des listes, etc. suivent leur ordre naturel (index 0 vers le haut, etc.).

le contrat d'IEnumerable nous garantit-il une certaine commande dans le cas général?

Non, il garantit uniquement l'énumération (chaque article une fois, etc.). IEnumerable n'a pas de commande garantie car il est également utilisable sur les articles non commandés.

Je connais LINQ First (), mais si IEnumerable ne dit pas un mot à propos de son ordre, cette extension est plutôt inutile.

Non, ce n'est pas le cas, car vous pouvez avoir un ordre intrinsèque. Vous donnez SQL comme exemple - le résultat est un IEnumerable, mais si j'ai déjà appliqué le classement (en utilisant OrderBy ()), le IEnumerable est ordonné par définition de LINQ. AsEnumerable (). First () m'obtient ensuite le premier élément par commande.

13
TomTom

Peut-être recherchez-vous l'interface IOrderedEnumerable ? Il est renvoyé par des méthodes d'extensions comme OrderBy() et permet un tri ultérieur avec ThenBy().

6

Vous mélangez deux points: l'énumération et la commande.

Lorsque vous énumérez sur IEnumerable, vous ne devez pas vous soucier de l'ordre. Vous travaillez avec l'interface et sa mise en œuvre doit se soucier de l'ordre.

Par exemple:

void Enumerate(IEnumerable sequence)
{
    // loop
}

SortedList<T> sortedList = ...
Enumerate (sortedList);

À l'intérieur de la méthode, c'est toujours une liste avec un ordre fixe, mais la méthode ne connaît pas l'implémentation d'interface particulière et sa particularité.

4
abatishchev