为什么GroupCollection和MatchCollection是非泛型的?

本文关键字:泛型 是非 MatchCollection GroupCollection 为什么 | 更新日期: 2023-09-27 18:12:14

当你想要一组c#中的正则表达式匹配时,你会得到一个MatchCollection。同样的处理一组基团和一个GroupCollection

然而,它们都是非泛型的,即使在4.5中,即使它会(据我所知):

  • 不破坏任何东西,因为IEnumerable<T>继承自IEnumerable
  • 使它更容易使用LINQ,例如,代替myMatchCollection.Cast<Match>().SomeLINQMethod()你可以只做myMatchCollection.SomeLINQMethod()
  • 使它更有效,因为你不需要强制转换它开始。
  • 没有太多的工作给团队。他们所需要做的就是将他们的内部实现从ArrayList更改为List<Match || Group>(见鬼,甚至像Match[] || Group[]这样的东西),并添加一个Match GetEnumerator方法,这应该不超过5分钟。

我的问题是:我错过了什么吗?他们为什么不能将它们更改为通用的,并且更好地与LINQ一起使用,还有其他原因吗?

为什么GroupCollection和MatchCollection是非泛型的?

  1. 改变现有的定义将是一个突破性的变化。
  2. 每个新功能都会产生机会成本,从而妨碍实现其他可能更高价值的功能。
  3. 感知收益(非常!?)很小。
  4. 围绕现有实现编写自己的通用包装器是直截了当的。

如果你不同意这些论点中的任何一个,向微软提出商业案例,说明他们错误地计算了收益-成本的决定。他们甚至可能会倾听并执行它;你有什么好损失的?

不会破坏任何东西,因为IEnumerable继承自IEnumerable。

大概不会。诚然,每一次改变都是突破性的改变,因为总会有一些奇怪的互动发生的风险。绝对保证没有破坏性更改的唯一方法是不更改任何内容。

虽然这也是不可接受的(否则任何事情都没有进展),但这是对任何变化的持续压力。

使它更容易在LINQ中使用,例如,代替myMatchCollection.Cast().SomeLINQMethod(),你可以直接使用myMatchCollection.SomeLINQMethod()

正确,这也是我认为这可能值得一做的原因。但请注意,在可能更改为泛型和linq存在之间存在几个框架版本。这一点我一会儿再讲。

使其更有效,因为您不需要在开始时强制转换它。

你不需要对MatchCollection的许多用法进行强制转换,只有当你通过接口使用它时才需要。

不要给团队太多的工作。他们所需要做的就是将内部实现从ArrayList改为List(甚至是Match[]||Group[]),并添加Match GetEnumerator方法,这应该不会超过5分钟。

这个变化是在。net Core的未来分支中完成的(即添加API而不是修复,为现有代码添加测试等),你可以在https://github.com/dotnet/corefx/commit/9a764c6fc139dbd3f3a526ad7def52178f1c71c3上看到,有1168个添加和88个删除,这是超过5分钟的工作,即使没有审查(当然有)。

请注意,没有必要从ArrayList更改为List<Match>List<Group>,因为这已经完成了。

如果把它从future拉到master,它确实会带来你所说的一些好处。

但是值得注意的是,即使是目前,如果你迭代MatchCollection,你也不会强制转换(内部代码可能是也可能不是,取决于你使用的版本,因为。net Core和Silverlight都已经在内部使用List<Match>,而其他人则没有)。如果强制进行强制类型转换,则强制类型转换相对便宜(不像所包含的元素是值类型)。

在那个时候,决定不值得为了相对较小的收益而承担相对较小的风险,特别是考虑到每个参与者都有其他事情要做。

在https://github.com/dotnet/corefx/issues/271,人们认为收益确实值得冒险。请注意,仅仅讨论风险就需要超过五分钟的时间。

还请注意,枚举的速度不如您在裸foreach中所希望的那样快,因为公共GetEnumerable()仍然返回IEnumerator而不是IEnumerator<Match>,因为更改这确实是一个破坏性的更改。