Elenco .tolist () enumera la raccolta
-
21-12-2019 - |
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
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
, nonmemcpy.
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 :