【发布时间】:2010-12-31 21:33:47
【问题描述】:
我正在阅读 Coders at Work 中对 Joshua Bloch 的采访,他对 Java 5 中泛型的引入感到遗憾。他不喜欢具体的实现,主要是因为对差异的支持(Java 的通配符)使它变得不必要地复杂。
据我所知,C# 3 没有任何明确的、有界通配符,例如您不能声明采用 Asset 集合或任何 Asset 子类(Java 中的void PriceBatch(Collection<? extends Asset> assets)?)的方法 PriceBatch。
有谁知道为什么没有在 C# 中添加通配符和边界?这些特性是为了让语言更简单而故意遗漏的,还是他们还没有实现?
编辑: 神圣的烟雾,来自 Eric Lippert 本人的 cmets!在阅读了他和 Paul 富有洞察力的 cmets 之后,我意识到至少支持上限,并且上面的示例可以翻译成 C# 为:
void PriceBatch<T>(ICollection<T> assets) where T : Asset
另一方面,正如 Eric 在他的第二条评论中所说,显然不支持下限,例如可能没有办法将这个(有点做作的)Java 代码直接翻译成 C#:
public class Asset {}
public class Derivative extends Asset {}
public class VanillaOption extends Derivative {}
public static <T extends Asset> void copyAssets(Collection<T> src, Collection<? super T> dst) {
for(T asset : src) dst.add(asset);
}
Collection<VanillaOption> src = new ArrayList<VanillaOption>();
[...]
Collection<Derivative> dst = new ArrayList<Derivative>();
[...]
copyAssets(src, dst);
我说的对吗?如果是这种情况,C# 有上限但没有下限是否有特殊原因?
【问题讨论】:
-
我不明白这个问题; C# 有界泛型,并且自 C# 2 起就有。你所得到的 Java 是否支持构造泛型类型的 call-site 协变和逆变?因为 C# 不支持它; C# 4 将支持 declaration-site 变化。
-
或者你得到的事实是,泛型方法上的类型参数边界只是必须派生的边界,而不是必须派生的边界? C#不支持后者;我相信 Java 和 Scala。
-
谢谢,我已经更新了问题。