想知道为什么 C# 正在转向更多基于模式的编程而不是传统方式。
例。 foreach
语句期望循环源有一个名为 GetEnumerator
的魔术方法它返回一个对象,该对象具有更多魔术方法,例如 MoveNext
和 Current
,但他们不要求任何特定的接口(interface)? C# 可以强制在 foreach
中使用一个类应该实现 IEnumerable
或 IEnumerable<T>
正如它对 using
所做的那样声明它期望在 using
中使用一个对象执行 IDisposable
的语句界面。
此外,我在 async
上看到了类似的趋势。/await
还有关键字....
当然这一定有充分的理由,但我觉得理解为什么编译器/CLR 需要“魔术方法”而不是依赖接口(interface)的原因似乎有点奇怪。
最佳答案
foreach
我会说这既是关于性能又是关于兼容性
- 如果您选择了
foreach
使用IEnumerable
它会使所有通用 值类型的集合迭代非常慢T
(因为 装箱/拆箱)。 - 如果您选择使用
IEnumerable<T>
遍历ArrayList
和 来自早期 .NET 版本的所有非泛型集合都不会被 可能。
我认为设计决策很好。当foreach
引入 (.NET 1.1) .NET 中没有关于泛型的内容(它们是在 .NET 2.0 中引入的)。选择IEnumerable
作为 foreach
的来源枚举会使它与通用集合一起使用时效果不佳,或者需要进行彻底的更改。我想设计师们已经知道他们将在不久之后引入泛型。
此外,将其声明为使用IEnumerable<T>
什么时候可用或IEnumerable
如果不是 没有太大区别,则使用可用 GetEnumerator
方法或不可用时不编译,是吗?
更新
正如@mikez 在评论中提到的,还有一个优势。当你不期待 GetEnumerator
返回 IEnumerator
/IEnumerator<T>
你可以回struct
并且在循环使用枚举器时不必担心装箱。
LINQ
当您使用 LINQ 和基于语法的查询时,同样的魔术方法情况也会发生。当你写作时
var results = from item in source
where item != "test"
select item.ToLower();
编译器将其转化为
var results = source.Where(x => x != "test")
.Select(x => x.ToLower());
而且因为无论什么界面,该代码都可以工作 source
实现同样适用于基于语法的查询。只要将其转换为基于方法的查询后,编译器可以正确分配每个方法调用,就可以了。
异步/等待
我不太确定,但我认为同样的事情也适用于 async
/await
.当您使用这些关键字时,编译器会为您自己生成一堆代码,然后像您自己编写代码一样进行编译。只要通过该转换生成的代码可以编译,一切都可以。
关于c# - 为什么在 C# 中进行基于模式的编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21070640/