Domanda

Attraverso i viaggi in Stackoverflow ci sono molti usi del metodo di estensione ToList() per un ICollection (o classi che derivano da ICollection<T>).

Ho tirato fuori il buone decompiler per dare un'occhiata al modo in cui viene eseguito il metodo di estensione ToList() e enumera la raccolta in qualsiasi momento. Attraversando la fonte che ho incontrato:

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

Ora questo è piuttosto semplice, quindi il metodo di estensione ToList() crea solo un nuovo List<T> con l'oggetto sorgente. La scavatura più a fondo nel costruttore dell'elenco mostra questa linea.

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

Come vuoi, scavare nel metodo CopyTo. Questo è dove sono rimasto bloccato. Dopo tutto lo scavo attraverso le chiamate del metodo arrivando alla chiamata del metodo finale extern

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

La mia domanda è (anche se non riesco a trovarlo) Il metodo di estensione ToList() (ICollection<T>.CopyTo()) ha iberato attraverso tutti gli oggetti della raccolta (array) quando eseguito?

Sottoquestione: dove posso trovare la fonte per il extern void Copy() sopra?

Modifica: Ho modificato la domanda direttamente come ho realizzato dopo che sto cercando di ottenere una specifica su un'interfaccia e non implementazione. Mi dispiace

È stato utile?

Soluzione

.

La mia domanda è (anche se non riesco a trovarlo) fa il ToList() Metodo di estensione (ICollection<T>.CopyTo()) Iberate attraverso tutto Oggetti della collezione (Array) quando eseguito?

No, non lo fa. Copia solo lo stoccaggio dell'array sottostante utilizzando Array.Copy.


.

Aggiornamento

Solo per assicurarsi che la mia risposta sia interpretata correttamente. ToList() non enumera la raccolta sorgente quando viene chiamato direttamente su un altro List<T> o T[] Array (o altra raccolta che implementa ICollection.CopyTo senza enumerare).

Quando chiami ToList<> E.G. su Enumerable.Range(0, 1000).ToList() ci sarà un'enumerazione. L'enumerazione verrà anche eseguita quando si utilizza qualsiasi metodo LINQ, ad es. myList.Select(x => x.PropertyName).ToList() causerà l'enumerazione.

fine di aggiornamento


.
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);
    }
}
.

Che utilizza il codice C ++ non gestito per farlo in modo efficiente:

.

Questo metodo è equivalente alla funzione standard c / c ++ memmove, non memcpy.

Da Metodo Array.Copy (array, array, INT32)

Altri suggerimenti

does the ToList() extension method (ICollection.CopyTo()) iterate through all objects of the Collection

It depends on how ICollection<T> is implemented in particular class.

For example, List<T> implementation just copies array (without iteration), because internally List<T> uses array as a storage. But nothing prevents you (or someone else) to write implementation, which will iterate though the source collection.

Where can I find the source for the extern void Copy() above

methods, marked by MethodImpl(MethodImplOptions.InternalCall), are implemented in unmanaged C++ code. I'm not sure, that there are any opened sources for them. But I suppose, that, ultimately, there's something like memcpy(...).

extern it means that function will be implemented in outside of C# code. It could be implemented in C/C++. More detail :

extern keyword

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top