通过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.
| 归档时间: |
|
| 查看次数: |
1075 次 |
| 最近记录: |