【问题标题】:Why does .NET Framework overload for arrays and IEnumerable & params []?为什么 .NET Framework 重载数组和 IEnumerable & params []?
【发布时间】:2018-05-24 06:29:40
【问题描述】:

在.NET框架中,有一些函数可以同时接受IEnumerableArray参数,或者params Array参数。

既然IEnumerable 可以满足任何提供Array 的调用代码,为什么要实现它?

另一方面,params Array 不会替换 IEnumerable,但是,它会替换 Array.

所以在我看来,只需要IEnumerableparams Array

问题:这背后的框架(如 .NET)的意图是什么?如果被调用者使用反射,是否向下兼容?


示例 1:

File.WriteAllLines(string path, string[] contents);
--> File.WriteAllLines(string path, IEnumerable<string> contents);

示例 2:

Path.Combine(string path1, string path2);
Path.Combine(string path1, string path2, string path3);
Path.Combine(string path1, string path2, string path3, string path4);
--> Path.Combine(params string[] paths);

【问题讨论】:

  • params string[]string[] 没有什么不同。当您使用params 时,编译器允许您使用语法糖。所以new[] {a,b,c}a,b,c 会被编译成同一个东西。

标签: c# .net frameworks


【解决方案1】:

对于示例 1:在这种特定情况下,the string[] is from .NET 2.0,而the IEnumerable&lt;string&gt; is from .NET 4.0。在引入 LINQ (.NET 3.5) 之后,IEnumerable&lt;T&gt; 的使用变得“酷”,而 IEnumerable&lt;T&gt; 在 .NET 中占据了中心位置。在此之前,数组是最常用的集合类型(可能是因为在 .NET 1.1 中它们是唯一的强类型基集合)。可能如果他们今天重写 .NET,他们就不会放置该方法的数组版本。

对于示例2,第四种方法需要一个数组,即一个额外的对象(创建一个对象是一种成本……有时你会尝试去除这个成本)。为了速度,一些方法有多个重载,这些重载具有所用参数的确切数量和类型。

注意还有第三种情况:数组可以加速方法的方法,因为它可以被多次重新读取。你不应该多次重读IEnumerable&lt;T&gt;,因为不能保证它可以被重读,或者重读它不会产生很大的成本。

示例:string.Concat(string[])string.Concat(IEnumerable&lt;T&gt;)。第一个版本可以预先计算新字符串的总长度并分配所需的确切空间(因此它将循环string[]两次,一次计算总Length,第二次复制strings到新的string)。第二个必须使用增长缓冲区,因为它只能读取一次IEnumerable&lt;T&gt;

【讨论】:

  • 示例 1: 我知道从一开始就没有泛型。您是否有理由设计框架来保持这些重载?是因为反思吗? 示例 2: 查看参考源,性能优化比想象的要多得多!看起来很合理......尤其是对于缓冲区连接。
  • @bytecode77 您不能在较新版本的 .NET 中删除方法,否则会使其与旧版本不兼容。删除东西是一个重大的改变。在 .NET Core 中,他们试图对 .NET Framework 进行一些修改,但最终他们阅读了很多内容,因为否则没有人会将他们的旧应用程序转换为 .NET Core(要做的更改太多)
猜你喜欢
  • 2011-02-15
  • 2021-05-01
  • 2020-07-22
  • 1970-01-01
  • 2021-08-11
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
  • 2015-10-08
相关资源
最近更新 更多