c# - 鸭子类型(duck typing)在 C# 编译器中键入

标签 c# compiler-construction idisposable duck-typing

注意不是关于如何在 C# 中实现或模拟 duck typing 的问题...

几年来,我一直认为某些 C# 语言功能依赖于语言本身定义的数据结构(对我来说,这似乎总是奇怪的先有鸡还是先有蛋的情况)。例如,我的印象是 foreach 循环只能用于实现了 IEnumerable 的类型。

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

我有点困惑,为什么 using block 和 IDisposable 似乎不是这种情况。编译器不能使用鸭子类型(duck typing)并寻找 Dispose 方法有什么特别的原因吗?这种不一致的原因是什么?

也许在 IDisposable 的幕后发生了其他事情?

讨论为什么您会曾经拥有一个带有未实现 IDisposable 的 Dispose 方法的对象超出了这个问题的范围:)

最佳答案

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

在 C# 2 之前,在 foreach 上使用此鸭子类型(duck typing)是实现强类型迭代器的唯一方式,也是不装箱迭代值类型的唯一方式。我怀疑如果 C# 和 .NET 有泛型开始,foreach需要 IEnumerable<T>相反,并没有让鸭子类型(duck typing)。

现在,编译器在我能想到的其他几个地方使用了这种鸭子类型(duck typing):

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

在这两种情况下,都可以更轻松地将功能添加到现有类型和接口(interface)中,而这些概念以前并不存在。

鉴于IDisposable自第一个版本以来一直在框架中,我认为鸭子类型(duck typing) using 不会有任何好处。陈述。我知道你明确地试图打折扣有 Dispose 的原因没有实现 IDisposable从讨论中,但我认为这是一个关键点。在语言中实现一项功能需要有充分的理由,我认为鸭子类型(duck typing)是一种超越支持已知接口(interface)的功能。如果这样做没有明显的好处,它就不会最终出现在语言中。

关于c# - 鸭子类型(duck typing)在 C# 编译器中键入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6368967/

相关文章:

python - 开始编写非上下文无关的编程语言的好资源是什么?

compiler-construction - 哪些因素影响所需的编译器?

idisposable - NDepend CQL 查询缺少 IDisposable 实现

c# - GC.KeepAlive 保留上下文

c# - 错误: exception of type 'System.NullReferenceException' occurred in exe

c# - 在相等性测试中使用字符串文字是否会创建新字符串?

c# - 为什么编译器无法推断对象数组类型?

c++ - 如何将包含#pragma optimize( "a") 的代码从 VC++7 移植到 VC++9?

c# - 在 C# 中处理非托管对象

c# 多条件排序