一尘不染

鸭子在C#编译器中键入

c#

注意不是 有关如何在C#中实现或模拟鸭子类型的问题…

几年来,我一直以为某些C#语言功能依赖于语言本身定义的数据结构(在我看来,这总是很奇怪的情况)。例如,我给人的印象是,该foreach循环仅可用于已实现的类型IEnumerable

从那时起,我开始理解C#编译器使用鸭子类型来确定对象是否可以在foreach循环中使用,GetEnumerator而不是寻找方法IEnumerable。这很有意义,因为它消除了鸡肉和鸡蛋的难题。

对于为什么不是这样,我有些困惑,而usingblock和似乎并非如此IDisposable。编译器无法使用鸭子类型和寻找Dispose方法有什么特殊原因吗?这种不一致的原因是什么?

也许IDisposable背后还有其他事情吗?

讨论为什么你会 永远 有未实现IDisposable Dispose方法的对象超出这个问题的范围:)


阅读 255

收藏
2020-05-19

共1个答案

一尘不染

没有什么特别之处IDisposable这里-但有 什么特别的迭代器。

C#2,使用这种类型的鸭子之前foreach 为你可以实现一个强类型的迭代器,并遍历值类型,而拳击的唯一途径。我 怀疑
如果C#和.NET都具有泛型,foreach那么就 需要 使用泛型IEnumerable<T>,而没有鸭子类型。

现在,编译器在其他几个我可以想到的地方使用了这种鸭子输入:

  • 集合初始化器寻找合适的Add重载(以及必须实现的类型IEnumerable,只是为了表明它确实是某种类型的集合);这允许灵活地添加单个项目,键/值对等
  • LINQ(Select等)-这是LINQ实现其灵活性的方式,允许针对多种类型使用相同的查询表达式格式,而无需更改IEnumerable<T>自身
  • C#5等待表达式需要GetAwaiter返回一个具有IsCompleted/ OnCompleted/ 的等待类型GetResult

在这两种情况下,这都使得将功能添加到现有类型和接口上变得更加容易,而以前的概念和概念并不存在。

鉴于IDisposable自第一个版本以来该框架就已经存在,因此我认为使用鸭子输入using语句不会有任何好处。我知道您明确尝试取消讨论中Dispose没有执行的原因IDisposable,但是我认为这很关键。有充分的理由在语言中实现功能,我认为鸭子类型是支持已知接口的重要功能。如果这样做没有明显的好处,那么它就不会以该语言出现。

2020-05-19