c# - 为什么将 List<T>.AddRange 方法设为通用方法会影响性能?

标签 c# .net performance generics covariance

我正在阅读 C# 深度(第 3 版),在第 13 章中,在讨论在 C# 4 中包含协变和逆变类型参数的部分中,做出了这样的声明:

The parameter for List.AddRange is of type IEnumerable<T>, so in this case you’re treating each list as an IEnumerable <IShape>—something that wouldn’t have been possible before. AddRange could have been written as a generic method with its own type parameter, but it wasn’t—doing this would’ve made some optimizations hard or impossible.

有人可以为这种说法提供一些理由吗?不清楚为什么对我来说是这样。

最佳答案

我猜它没有写成 void AddRange<T>(IEnumerable<T> items)是因为它在 IEnumerable<T> 时进行了优化是一个 ICollection<T> .当 IEnumerable<T>是一个 ICollection<T> , AddRange 内部调用 ICollection<T>.CopyTo ,第一个参数为T[] . (注意 List<T> 的底层存储机制是 T[] )。

基本类型的数组与派生类型的数组不同,因此您不能这样做,例如:

object[] objs = new object[4];
var collection = (new string[4]) as ICollection<string>;
collection.CopyTo(objs,0); //Cannot convert object[] to string[]

这是“不可能”的优化。

你可以在这里查看源代码: https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,79de3e39e69a4811

好像AddRange应该检查 T[]List<T> , 然后做 Array.Copy在那些情况下,但我猜是-100。您可能会对 Array.ToArray() 的内容感到有些惊讶。也不行。

关于c# - 为什么将 List<T>.AddRange 方法设为通用方法会影响性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51744440/

相关文章:

c# - 从 Windows 服务中调用时 SSL Web 服务调用失败

c# - 如何在 TimeStampToken (Bouncy CaSTLe) 中获取签名

c# - ASP.NET Core 相当于 ASP.NET MVC 5 的 HttpException

C# GetManifestResourceStream 返回 null

c# - 为什么后续的直接方法调用比第一次调用快很多?

python - 将 functools.partial 与字符串方法一起使用的替代方法

android - LayoutInflater是不是每次都加载xml?

c# - "deep freeze"是如何工作的?

c# - 验证 IEnumerable<dynamic> 内容的单元测试

c# - .NET Winforms 中让用户输入时间范围的好方法?