C#中的协方差和协方差 [英] Covariance and Contravariance in C#

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

问题描述

首先,我是Java开发人员,正在学习C#编程。这样,我就将自己所学与所学知识进行了比较。

I will start by saying that I am Java developer learning to program in C#. As such I do comparisons of what I know with what I am learning.

我已经使用C#泛型了几个小时了,除了使用两个使用协方差和逆方差的示例。我正在读的书在这个学科上不是很好。我当然会在网上寻找更多信息,但是尽管这样做,也许您可​​以帮我找到以下Java代码的C#实现。

I have been playing with C# generics for a few hours now, and I have been able to reproduce the same things I know in Java in C#, with the exception of a couple of examples using covariance and contravariance. The book I am reading is not very good in the subject. I will certainly seek more info on the web, but while I do that, perhaps you can help me find a C# implementation for the following Java code.

一个例子值得一千个单词,我希望通过寻找一个好的代码示例,我能够更快地吸收它。

An example is worth a thousand words, and I was hoping that by looking a good code sample I will be able to assimilate this more rapidly.

协方差

在Java中,我可以这样做:

In Java I can do something like this:

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是协变类型。是吗?

Now I did discover that C# supports covariance/contravariance only on interfaces and as long as they have been explicitly declared to do so (out/in). I think I was not able to reproduce this case, because I could not find a common ancestor of all numbers, but I believe that I could have used IEnumerable to implement such thing if a common ancestor exists. Since IEnumerable is a covariant type. Right?

对如何实施以上列表有任何想法吗?只要指出我正确的方向。是否存在所有数字类型的共同祖先?

Any thoughts on how to implement the list above? Just point me into the right direction. Is there any common ancestor of all numeric types?

逆性

逆性我尝试的示例如下。在Java中,我可以这样做将一个列表复制到另一个列表中。

The contravariance example I tried was the following. In Java I can do this to copy one list into another.

public static void copy(List<? extends Number> source, List<? super Number> destiny){
    for(Number number : source) {
       destiny.add(number);
    }
}

然后,我可以将其与如下互变量类型一起使用:

Then I could use it with contravariant types as follows:

List<Object> anything = new ArrayList<Object>();
List<Integer> myInts = asList(1,2,3,4,5);
copy(myInts, anything);

我的基本问题是,尝试在C#中实现这一点是因为我找不到一个接口协变和逆变同时出现,就像我上面的示例中的List一样。也许可以在C#中使用两个不同的接口来完成。

My basic problem, trying to implement this in C# is that I could not find an interface that was both covariant and contravariant at the same time, as it is case of List in my example above. Maybe it can be done with two different interfaces in C#.

是否有实现想法的想法?

Any thoughts on how to implement this?

非常感谢大家为您提供的任何答案。我很确定我将从您可以提供的任何示例中学到很多东西。

Thank you very much to everyone for any answers you can contribute. I am pretty sure I will learn a lot from any example you can provide.

推荐答案

对于问题的第二部分,您不需要矛盾,您需要做的就是声明第一种可以转换为第二种。同样,使用 where TSource:TDest 语法执行此操作。这是一个完整的示例(显示了如何使用扩展方法):

For the 2nd part to your question, you don't need contravariance, all you need to do is state that the first type can be cast to the second. Again, use the where TSource: TDest syntax to do this. Here is a full example (that shows how to do it with an extension method):

static class ListCopy
{
    public static void ListCopyToEnd<TSource, TDest>(this IList<TSource> sourceList, IList<TDest> destList)
        where TSource : TDest // This lets us cast from TSource to TDest in the method.
    {
        foreach (TSource item in sourceList)
        {
            destList.Add(item);
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        List<int> intList = new List<int> { 1, 2, 3 };
        List<object> objList = new List<object>(); ;

        ListCopy.ListCopyToEnd(intList, objList);
        // ListCopyToEnd is an extension method
        // This calls it for a second time on the same objList (copying values again).
        intList.ListCopyToEnd(objList);

        foreach (object obj in objList)
        {
            Console.WriteLine(obj);
        }
        Console.ReadLine();
    }

这篇关于C#中的协方差和协方差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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