List <t> .ToList()枚举集合</t>

时间:2014-01-09 06:13:20

标签: 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);
}

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

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

如您所愿,您将深入研究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);

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

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

编辑:我已经直接编辑了这个问题,因为我意识到之后我正在尝试获取接口的规范而不是实现。遗憾

3 个答案:

答案 0 :(得分:12)

  

我的问题是(虽然我似乎无法找到它)ToList()   扩展方法(ICollection<T>.CopyTo())遍历所有   集合中的对象(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);
    }
}

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

  

此方法等同于标准C / C ++函数memmove,而不是memcpy.

     

来自Array.Copy Method (Array, Array, Int32)

答案 1 :(得分:1)

  

ToList()扩展方法(ICollection.CopyTo())是否遍历Collection的所有对象

这取决于特定类中ICollection<T>的实现方式。

例如,List<T>实现只复制数组(不进行迭代),因为内部List<T>使用数组作为存储。但没有什么可以阻止你(或其他人)编写实现,它将迭代源集合。

  

我在哪里可以找到extern void Copy()上面的源代码

MethodImpl(MethodImplOptions.InternalCall)标记的

方法在非托管C ++代码中实现。我不确定,他们有任何开源。但我想,最终,有一些像memcpy(...)

答案 2 :(得分:0)

extern 表示该函数将在C#代码之外实现。它可以用C / C ++实现。更多细节:

  

extern keyword