【发布时间】:2012-04-06 01:31:15
【问题描述】:
首先我要说我是一名学习 C# 编程的 Java 开发人员。因此,我将我所知道的与我所学的进行比较。
我已经用 C# 泛型玩了几个小时了,我已经能够在 C# 中重现我在 Java 中所知道的相同的东西,除了几个使用协变和逆变的例子。我正在读的这本书在这方面不是很好。我当然会在网上寻找更多信息,但在我这样做的同时,也许您可以帮我找到以下 Java 代码的 C# 实现。
一个例子值一千字,我希望通过查看一个好的代码示例,我能够更快地吸收这一点。
协方差
在 Java 中我可以这样做:
public static double sum(List<? extends Number> numbers) {
double summation = 0.0;
for(Number number : numbers){
summation += number.doubleValue();
}
return summation;
}
我可以这样使用这段代码:
List<Integer> myInts = asList(1,2,3,4,5);
List<Double> myDoubles = asList(3.14, 5.5, 78.9);
List<Long> myLongs = asList(1L, 2L, 3L);
double result = 0.0;
result = sum(myInts);
result = sum(myDoubles)
result = sum(myLongs);
现在我确实发现 C# 仅在接口上支持协变/逆变,只要它们已明确声明(出/入)即可。我想我无法重现这种情况,因为我找不到所有数字的共同祖先,但我相信如果存在共同祖先,我可以使用 IEnumerable 来实现这样的事情。由于 IEnumerable 是协变类型。对吧?
对如何实现上面的列表有任何想法吗?只需指出我正确的方向。所有数值类型是否有共同的祖先?
逆变
我尝试的逆变示例如下。在 Java 中,我可以这样做将一个列表复制到另一个列表中。
public static void copy(List<? extends Number> source, List<? super Number> destiny){
for(Number number : source) {
destiny.add(number);
}
}
然后我可以将它与逆变类型一起使用,如下所示:
List<Object> anything = new ArrayList<Object>();
List<Integer> myInts = asList(1,2,3,4,5);
copy(myInts, anything);
我的基本问题是,尝试在 C# 中实现这一点是我找不到一个同时是协变和逆变的接口,就像上面示例中的 List 一样。也许可以用 C# 中的两个不同接口来完成。
关于如何实现这个有什么想法吗?
非常感谢大家提供的任何答案。我很确定我会从您提供的任何示例中学到很多东西。
【问题讨论】:
-
我很确定你不能,因为 .NET 团队以其无限的智慧没有提供一种方法来讨论基本类型(例如,数字、浮点)的类。因此,您不能在泛型类型的参数的泛型方法中使用 operator +,并且无法指定您应该能够使用。这是一个明显的洞,但它就在那里。
-
我前段时间问了一个问题,有一些类似的概念:stackoverflow.com/questions/5516459/…
标签: c# java covariance contravariance