List <T> .ToList()枚举集合

Nic*_*ico 9 c# icollection

通过StackOverflow中的旅行,有许多ToList()用于ICollection(或派生自的类ICollection<T>)的扩展方法.

我已经退出了好的'反编译器,看看ToList()扩展方法是如何执行的,并且随时枚举集合.通过源头我遇到了:

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

现在这非常简单,因此ToList()扩展方法只是List<T>使用源对象创建一个新的.深入挖掘List构造函数会显示此行.

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

就像你想的那样,你会深入研究这种CopyTo方法.这是我被卡住的地方.在完成所有挖掘方法调用之后,我们进入最后的extern方法调用

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

我的问题是(虽然我似乎无法找到它)ToList()扩展方法(ICollection<T>.CopyTo())在执行时是否遍历Collection(Array)的所有对象?

子问题:我在哪里可以找到上述来源extern void Copy()

编辑:我已经直接编辑了问题,因为我意识到之后我试图获得接口的规范而不是实现.抱歉

Mar*_*zek 13

我的问题是(虽然我似乎无法找到它)ToList() 扩展方法在执行时是否(ICollection<T>.CopyTo())遍历Collection(Array)的所有对象?

不,不是的.它只是使用复制底层数组存储Array.Copy.


更新

只是为了确保我的答案得到正确解释.ToList()当直接在另一个List<T>T[]数组(或其他没有枚举器的集合)上调用源集合时,它不会枚举它ICollection.CopyTo.

当你打电话时ToList<>,Enumerable.Range(0, 1000).ToList()会有一个枚举.当您使用任何LINQ方法时,也将执行枚举,例如,myList.Select(x => x.PropertyName).ToList()将导致枚举.

更新结束


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);
    }
}
Run Code Online (Sandbox Code Playgroud)

它使用非托管c ++代码以有效的方式执行此操作:

这个方法相当于标准的C/C++函数memmove,而不是memcpy.

来自Array.CopyMethod(Array,Array,Int32)