Question

À travers les voyages dans StackOverflow, il existe de nombreuses utilisations du ToList() méthode d'extension pour un ICollection (ou des classes qui dérivent de ICollection<T>).

J'ai sorti le bon vieux décompilateur pour voir comment le ToList() La méthode d'extension est exécutée et énumère la collection à tout moment.En parcourant la source que j'ai trouvée :

[__DynamicallyInvokable]
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    return new List<TSource>(source);
}

Maintenant, c'est assez simple, donc le ToList() la méthode d'extension crée simplement un nouveau List<T> avec l'objet source.En creusant plus profondément dans le constructeur List, on montre cette ligne.

ICollection<T> ts = collection as ICollection<T>;
//.. ommited code
ts.CopyTo(this._items, 0);

Comme vous le feriez, vous creuseriez dans le CopyTo méthode.C'est là que je suis resté coincé.Après avoir parcouru tous les appels de méthode, nous arrivons au final extern appel de méthode

[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[SecurityCritical]
internal static extern void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable);

Ma question est (même si je n'arrive pas à la trouver) est-ce que le ToList() méthode d'extension (ICollection<T>.CopyTo()) parcourir tous les objets de la collection (tableau) lors de son exécution ?

Sous-question :Où puis-je trouver la source du extern void Copy() au-dessus de?

Modifier: J'ai édité la question directement car j'ai réalisé après cela que j'essayais d'obtenir une spécification sur une interface et non une implémentation.Désolé

Était-ce utile?

La solution

Ma question est (même si je n'arrive pas à la trouver) est-ce que le ToList()méthode d'extension (ICollection<T>.CopyTo()) itérer à travers tous les objets de la collection (Array) une fois exécuté ?

Non. Il copie simplement le stockage du tableau sous-jacent en utilisant Array.Copy.


Mise à jour

Juste pour m'assurer que ma réponse est interprétée correctement. ToList() n'énumère pas la collection source lorsqu'elle est appelée directement sur un autre List<T> ou T[] tableau (ou autre collection qui implémente ICollection.CopyTo sans enquêteur).

Quand vous appelez ToList<> par exemple.sur Enumerable.Range(0, 1000).ToList() il y aura une énumération.L'énumération sera également effectuée lorsque vous utilisez une méthode LINQ, par ex. myList.Select(x => x.PropertyName).ToList() entraînera un dénombrement.

Fin de la mise à jour


void ICollection.CopyTo(Array array, int arrayIndex)
{
    if (array != null && array.Rank != 1)
    {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
    }
    try
    {
        Array.Copy(this._items, 0, array, arrayIndex, this._size);
    }
    catch (ArrayTypeMismatchException)
    {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
    }
}

qui utilise du code C++ non géré pour le faire de manière efficace :

Cette méthode est équivalente à la fonction standard C/C++ memmove, pas memcpy.

depuis Array.Copy Méthode (Array, Array, Int32)

Autres conseils

la méthode d'extension ToList() (ICollection.CopyTo()) parcourt-elle tous les objets de la collection

Cela dépend de la façon dont ICollection<T> est implémenté dans une classe particulière.

Par exemple, List<T> l'implémentation copie simplement le tableau (sans itération), car en interne List<T> utilise le tableau comme stockage.Mais rien ne vous empêche (ou quelqu'un d'autre) d'écrire une implémentation, qui parcourra la collection source.

Où puis-je trouver la source de la copie externe vide () ci-dessus

méthodes, marquées par MethodImpl(MethodImplOptions.InternalCall), sont implémentés dans du code C++ non managé.Je ne suis pas sûr qu'il existe des sources ouvertes pour eux.Mais je suppose qu'en fin de compte, il y a quelque chose comme memcpy(...).

externe cela signifie que la fonction sera implémentée en dehors du code C#.Il pourrait être implémenté en C/C++.Plus de détails :

mot clé externe

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top