Ken*_*man 4 c# generics types inference covariance
只是好奇:当然,我们都知道泛型类型推断的一般情况是不可判定的.所以C#根本不做任何类型的子类型:如果Foo <T>是泛型的,Foo <int>不是Foo <T>的子类型,或Foo <Object>或其他任何你可能的类型做饭.当然,我们都用丑陋的界面或抽象类定义来解决这个问题.
但是......如果你无法解决一般性问题,为什么不将解决方案限制在容易的情况下.例如,在上面的列表中,显然Foo <int>是Foo <T>的子类型,并且检查它是微不足道的.检查Foo <Object>是一样的.
如果他们只是说,那么还有其他一些深深的恐怖会从深渊蔓延出来,我们会尽我们所能吗?或者这只是微软语言人员的某种宗教纯洁?
这是一个非常古老的线程.这些天,C#有var,它解决了我抱怨的一半,然后使用Linq风格的匿名代表,有一个很好的表示法,不需要输入两次相同的东西.因此,我反对的每一个方面都已经通过最近对C#的更改得到了解决(或者我只是花了一些时间来了解我刚发布帖子时刚刚介绍的内容......)我使用这些新内容现在在Isis2系统中可靠的云计算功能(isis2.codeplex.com),我认为该库具有非常干净的外观和感觉.看看它,让我知道你的想法). - Ken Birman(2014年7月)
他们已经为许多"简单"案例解决了这个问题:C#4.0支持接口和委托中泛型类型参数的协方差和逆变.但不幸的是没有课程.
解决此限制很容易:
List<Foo> foos = bars.Select(bar => (Foo)bar).ToList();
Run Code Online (Sandbox Code Playgroud)
它是OBVIOUS,
Foo<int>是一个子类型Foo<T>
也许对你而言,但对我而言.
对我来说,这种冲入类型系统的巨大漏洞是不可接受的.如果你想将类型安全性抛出窗口,我宁愿使用实际上为这些东西设计的动态类型语言.
数组是协变的这一事实,即使已知这会破坏类型安全性,这已经足够糟糕了,现在你想打破它的一切吗?
这是类型系统的核心所在.所有类型系统都是拒绝程序.由于赖斯的定理,那些被拒绝的程序包括完美的类型安全的程序.
这是一个巨大的成本.带走表现力,阻止我编写有用的程序.为了证明这个成本合理,类型系统更好地支付了大量的时间.它基本上有两种方法:在程序级别和类型安全性的类型级别上回馈表达性.
前者已经出局了,原因很简单,因为C#的类型系统不够强大,不能让我表达任何有趣的东西.这只留下后者,由于null协变阵列,不受限制的副作用等原因,它已经处于非常不稳定的基础unsafe上.通过使泛型类型自动协变,您或多或少地完全消除了剩下的最后一种类型安全性.
只有极少数情况下S <: T ? G<S> <: G<T>实际上是类型安全的.(IEnumerable就是这样一个例子.)并且可能同样很多只有S <: T ? G<T> <: G<S>类型安全的情况.(IObservable,IComparer,IComparable,IEqualityComparer.)通常,既不 G<S> <: G<T>也不G<T> <: G<S>是类型安全.
| 归档时间: |
|
| 查看次数: |
689 次 |
| 最近记录: |