# 鴨子在C＃編譯器中輸入

Note This is not a question about how to implement or emulate duck typing in C#...

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.

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.

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?

## 最佳答案

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 instead, and not had the duck typing.

• Collection initializers look for a suitable Add overload (as well as the type having to implement IEnumerable, just to show that it really is a collection of some kind); this allows for flexible adding of single items, key/value pairs etc
• LINQ (Select etc) - this is how LINQ achieves its flexibility, allowing the same query expression format against multiple types, without having to change IEnumerable itself
• The C# 5 await expressions require GetAwaiter to return an awaiter type which has IsCompleted/OnCompleted/GetResult