一千萬個為什麽

搜索

鴨子在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?

也許還有其他東西在IDisposable的引擎蓋下?

討論為什麽永遠擁有一個沒有實現IDisposable的Dispose方法的對象超出了這個問題的範圍:)

最佳答案

這裏的 IDisposable 並沒有什麽特別之處 - 但是 是關於叠代器的特別之處。

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

在這兩種情況下,這使得更容易將功能添加到現有類型和接口,而這些概念之前並不存在。

鑒於 IDisposable 自第一個版本以來一直在框架中,我認為使用語句輸入並不會有任何好處。我知道你明確地試圖在沒有從討論中實現 IDisposable 的情況下忽略了 Dispose 的原因,但我認為這是一個關鍵點。需要有充分的理由在語言中實現一個功能,我認為鴨子打字是一種超越支持已知界面的功能。如果這樣做沒有明顯的好處,它將不會以語言結束。

轉載註明原文: 鴨子在C#編譯器中輸入