鸭在C#编译器中键入 [英] Duck typing in the C# compiler

查看:181
本文介绍了鸭在C#编译器中键入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意这是不是有关如何在C#中实现或模拟鸭式键入的问题...



几年来,我的印象是,某些C#语言特性是依赖于语言本身定义的数据结构(对我来说,这似乎是一个奇怪的鸡蛋和鸡蛋场景)。例如,我的印象是 foreach 循环只能用于实现 IEnumerable 的类型。 / p>

从那时起,我就明白C#编译器使用鸭式类型来确定一个对象是否可以在foreach循环中使用,查找 GetEnumerator 方法,而不是 IEnumerable 。这使得很有意义,因为它删除了鸡&



我有点困惑,为什么这不是似乎不是这样的情况与使用 block和 IDisposable 。有没有什么特别的原因编译器不能使用鸭类型&查找 Dispose 方法?



也许在IDisposable下面还有其他的事情发生?



em>讨论为什么有一个没有实现IDisposable的Dispose方法的对象不在此问题的范围之内:)


IDisposable 这里没有什么特别的,但是特殊的迭代器。



在C#2之前,在 foreach 上使用此鸭类型只是可以实现一个强类型的迭代器,也是在没有装箱的情况下迭代值类型的唯一方法。我可疑如果C#和.NET有泛型开头, foreach 会有必需 IEnumerable< T> ,而不是鸭子类型。



现在编译器使用这种鸭类型其他地方我可以想到:




  • 集合初始化器寻找一个合适的 Add overload (以及类型必须实现 IEnumerable ,只是为了表明它真的是某种类型的集合);这允许灵活添加单个项目,键/值对等。

  • LINQ(选择等) - 这是LINQ如何实现而不必更改 IEnumerable< T> 本身

  • C#5等待表达式require GetAwaiter 返回一个awaiter类型,它具有 IsCompleted / OnCompleted / GetResult



在这两种情况下,



由于 IDisposable 已经存在,框架自第一个版本,我不认为有任何好处在鸭类型使用语句。我知道你明确试图在讨论中不实现 IDisposable 而优惠 Dispose 的原因,但我认为这是一个要害。需要有良好的理由在语言中实现一个特性,我认为鸭式打字是一个支持已知接口的功能。如果这样做没有明显的好处,它将不会以语言结束。


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?

Perhaps there's something else going on under the hood with IDisposable?

Discussing why you would ever have an object with a Dispose method that didn't implement IDisposable is outside the scope of this question :)

解决方案

There's nothing special about IDisposable here - but there is something special about iterators.

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:

  • 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<T> itself
  • The C# 5 await expressions require GetAwaiter to return an awaiter type which has IsCompleted / 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.

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#编译器中键入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆