Con*_*der 8 c# foreach iterator
想知道为什么C#正朝着更多基于模式的编程而不是传统方式发展.
防爆.该foreach声明预计,循环源已经被称为魔术方法GetEnumerator,它返回它有几个魔术方法类似于对象MoveNext和Current,但他们并没有强制任何特定的接口?C#可以强制要求使用的类foreach应该实现,IEnumerable或者IEnumerable<T>对using语句执行,因为它期望在using语句中使用对象来实现IDisposable接口.
此外,我看到async/ await关键字也有类似的趋势....
当然必须有一个很好的理由,但是我理解编译器/ CLR需要"魔术方法"而不是依赖接口的原因似乎有点奇怪.
Mar*_*zek 12
foreach
我会说这是关于性能和兼容性的
foreach使用IEnumerable它会使得所有泛型集合迭代对于值类型来说非常慢T(因为装箱/取消装箱).IEnumerable<T>迭代ArrayList,那么早期.NET版本的所有非泛型集合都是不可能的.我认为设计决定很好.何时foreach推出(.NET 1.1),.NET中的泛型(它们是在.NET 2.0中引入)并不存在.选择枚举IEnumerable的来源foreach会使得它与通用集合的使用不佳或需要彻底改变.我想设计师已经知道他们将在很久以后推出仿制药.
Additionaly,宣称它作为使用IEnumerable<T>时,它的可用或IEnumerable当它不没有太大的不同,然后利用现有的GetEnumerator方法或当它不可用,不进行编译,是吗?
更新
正如@mikez在评论中提到的那样,还有一个优点.如果您不希望GetEnumerator返回IEnumerator/ IEnumerator<T>您可以返回struct并且在循环使用枚举器时不必担心装箱.
LINQ
使用LINQ和基于语法的查询时会出现相同的魔术方法情况.当你写作
var results = from item in source
where item != "test"
select item.ToLower();
Run Code Online (Sandbox Code Playgroud)
它由编译器转换为
var results = source.Where(x => x != "test")
.Select(x => x.ToLower());
Run Code Online (Sandbox Code Playgroud)
并且因为无论什么接口source实现,该代码都可以工作,这同样适用于基于语法的查询.只要将其转换为基于方法的查询,每个方法调用都可以通过编译器正确分配,一切正常.
异步/ AWAIT
我不是那么肯定,但认为同样的事情适用于async/ await.当您使用这些关键字时,编译器会为您自己生成一堆代码,然后将其编译为您自己编写代码.只要可以编译由该转换生成的代码,一切都可以.
| 归档时间: |
|
| 查看次数: |
378 次 |
| 最近记录: |