Mat*_*vey 61 c# compiler-construction idisposable duck-typing
注意这不是关于如何在C#中实现或模拟duck typing的问题...
几年来,我的印象是某些C#语言特性对语言本身定义的数据结构感到沮丧(这对我来说似乎总是一个奇怪的鸡蛋和鸡蛋场景).例如,我的印象是foreach循环只能用于实现的类型IEnumerable.
从那时起,我开始明白C#编译器使用duck typing来确定是否可以在foreach循环中使用对象,GetEnumerator而不是查找方法IEnumerable.这很有意义,因为它消除了鸡蛋和鸡蛋的难题.
我有点困惑,为什么这不是using块的情况似乎并非如此IDisposable.是否有任何特殊原因编译器不能使用duck typing并查找Dispose方法?造成这种不一致的原因是什么?
或许还有其他东西在IDisposable的引擎盖下进行?
讨论为什么你会永远有未实现IDisposable是这个问题的范围之外的Dispose方法的对象:)
Jon*_*eet 39
没有什么特别之处IDisposable这里-但有是什么特别的迭代器.
在C#2之前,使用这种duck类型foreach是唯一可以实现强类型迭代器的方法,也是在没有装箱的情况下迭代值类型的唯一方法.我怀疑,如果C#和.NET已经开始使用泛型,foreach那就需要了 IEnumerable<T>,而不是打字.
现在,编译器在我能想到的其他几个地方使用这种鸭子类型:
Add重载(以及必须实现的类型IEnumerable,只是为了表明它确实是某种类型的集合); 这允许灵活地添加单个项目,键/值对等Select等) - 这就是LINQ实现其灵活性的方式,允许针对多种类型使用相同的查询表达式格式,而无需IEnumerable<T>自行更改GetAwaiter返回其具有awaiter类型IsCompleted/ OnCompleted/GetResult在这两种情况下,这使得更容易将功能添加到现有类型和接口,而这些概念之前并不存在.
鉴于IDisposable自第一个版本以来一直在框架中,我认为在键入using语句时没有任何好处.我知道你明确地试图忽略Dispose没有IDisposable从讨论中实现的原因,但我认为这是一个关键点.需要有充分的理由在语言中实现一个功能,我认为鸭子打字是一种超越支持已知界面的功能.如果这样做没有明显的好处,它将不会以语言结束.
Eam*_*nne 12
没有鸡肉和鸡蛋:   foreach可能取决于IEnumerable因为IEnumerable不依赖foreach.未实施的集合允许foreach的原因IEnumerable可能主要是历史性的:
在C#中,集合类不一定要从IEnumerable和IEnumerator继承,以便与foreach兼容; 只要该类具有所需的GetEnumerator,MoveNext,Reset和Current成员,它将与foreach一起使用.省略接口的优点是允许您将Current的返回类型定义为比对象更具体,从而提供类型安全性.
此外,并非所有鸡和蛋问题都是实际问题:例如,函数可以调用自身(递归!)或引用类型可以包含自身(如链接列表).
因此,当using它们出现时为什么他们会使用一些棘手的东西来指定为鸭子打字时他们可以简单地说:实施IDisposable?从根本上说,通过使用duck类型,你可以在类型系统周围进行最终运行,这仅在类型系统不足以(或不切实际)解决问题时才有用.
| 归档时间: | 
 | 
| 查看次数: | 4967 次 | 
| 最近记录: |