问题描述
注意这是的不的一个有关如何实现或者用C模仿鸭子类型的问题#...
Note This is not a question about how to implement or emulate duck typing in C#...
几年来,我是IM pression某些C#语言的特点进行depdendent在语言本身定义的数据结构下(这似乎总是像一个奇怪的鸡肉和放大器;蛋的情况对我来说)。例如,我是IM pression的的foreach
循环是仅可用于实现类型下使用的IEnumerable
。
For several years I was under the impression that certain C# language features were depdendent on data structures defined in the language itself (which always seemed like an odd chicken & egg scenario to me). For example, I was under the impression that the foreach
loop was only available to use with types that implemented IEnumerable
.
从那时起,我认识到,C#编译器使用鸭子类型,以确定是否一个对象可以在foreach循环使用,寻找的GetEnumerator
方法,而比的IEnumerable
。这使得有很大的意义,因为它消除了鸡肉和放大器;鸡蛋难题。
Since then I've come to understand that the C# compiler uses duck typing to determine whether an object can be used in a foreach loop, looking for a GetEnumerator
method rather than IEnumerable
. This makes a lot of sense as it removes the chicken & egg conundrum.
我有点困惑,为什么这不能似乎没有要与使用
块和 IDisposable的。有没有什么特别的原因,编译器不能使用鸭打字和放大器;寻找一个
的Dispose
的方法?什么是这种不一致的原因是什么?
I'm a little confused as to why this isn't doesn't seem to be the case with the
using
block and IDisposable
. Is there any particular reason the compiler can't use duck typing & look for a Dispose
method? What's the reason for this inconsistency?
也许有什么东西与IDisposable的引擎盖下别的功呢?
Perhaps there's something else gong on under the hood with IDisposable?
的讨论为什么你会曾经有未实现IDisposable是这个问题的范围Dispose方法的对象:)的
Discussing why you would ever have an object with a Dispose method that didn't implement IDisposable is outside the scope of this question :)
推荐答案
有什么特别的
的IDisposable
在这里 - 但有是的什么特别的迭代器。
There's nothing special about
IDisposable
here - but there is something special about iterators.
在C#2,使用上
的foreach
这只鸭子类型是的只有的是你可以实现一个强类型的迭代器,也是唯一的迭代值类型,而拳方式。我的犯罪嫌疑人的,如果C#和.NET已经有仿制药,开始时,的foreach
会有的需要的的IEnumerable< T>
来代替,并且没有鸭打字
Before C# 2, using this duck type on
foreach
was the only was you could implement a strongly-typed iterator, and also the only way of iterating over value types without boxing. I suspect that if C# and .NET had had generics to start with, foreach
would have required IEnumerable<T>
instead, and not had the duck typing.
现在的编译器使用这种鸭打字一对夫妇的其他地方我能想到的:
Now the compiler uses this sort of duck typing in a couple of other places I can think of:
- 集合初始化寻找一个合适的
添加
过载(以及具有实施的IEnumerable
,只是类型表明它确实是某种形式的集合);这允许灵活添加单个项目,键/值对等 - LINQ(
选择
等等) - 这是LINQ如何实现它的灵活性,允许对多种类型相同的查询前pression格式,而不必更改的IEnumerable&LT; T&GT;
本身 - 的C#5等候前pressions要求
GetAwaiter
返回它有一个awaiter键入IsCompleted
/OnCompleted
/调用getResult
Collection initializers look for a suitable
Add
overload (as well as the type having to implementIEnumerable
, just to show that it really is a collection of some kind); this allows for flexible adding of single items, key/value pairs etcLINQ (
Select
etc) - this is how LINQ achieves its flexibility, allowing the same query expression format against multiple types, without having to changeIEnumerable<T>
itselfThe C# 5 await expressions require
GetAwaiter
to return an awaiter type which hasIsCompleted
/OnCompleted
/GetResult
在这两种情况下,这使得它更容易的功能添加到现有类型和接口,其中该概念不存在较早前
In both cases this makes it easier to add the feature to existing types and interfaces, where the concept didn't exist earlier on.
由于
的IDisposable
自第一个版本已经在框架中,我不认为会有鸭键入任何利益使用
语句。我知道你明确地试图打折的原因有的Dispose
没有实施的IDisposable
从讨论,但我认为这是一个要害。有必须实现的语言功能很好的理由,而我认为,鸭打字是一个功能之上和超越支持现有的接口。如果没有明显的好处在这样做时,它不会在语言中结束。
Given that
IDisposable
has been in the framework since the very first version, I don't think there would be any benefit in duck typing the using
statement. I know you explicitly tried to discount the reasons for having Dispose
without implementing IDisposable
from the discussion, but I think it's a crucial point. There need to be good reasons to implement a feature in the language, and I would argue that duck typing is a feature above-and-beyond supporting a known interface. If there's no clear benefit in doing so, it won't end up in the language.
这篇关于在C#编译器鸭打字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!