【问题标题】:Understanding Covariance and Contravariance in C# 4.0了解 C# 4.0 中的协变和逆变
【发布时间】:2009-11-12 19:52:40
【问题描述】:

我在第 9 频道观看了有关它的视频,但我并不太了解。

有人可以给我一个简单易懂的例子吗?之后可能会如何在实践中使用?

【问题讨论】:

  • channel9.msdn.com - 有关 microsoft 开发框架的视频集合,以及更多内容 :)
  • stackoverflow.com/questions/1078423/… 应该会回答你很多关于它的问题(另请参阅 Jon Skeet 对 Eric Lippert 博客的链接。
  • 是的,它就像一个播客,有一些非常好的 Anders 的 c# 视频等。

标签: c# .net covariance contravariance


【解决方案1】:

你可能想看看这个博客,他做了很棒的解释,但我认为需要更多的例子来为人们澄清它,因为这进入了一个非常难以理解的领域,但是,文章下面的引文总结得很好。

http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html

“协变和逆变”是什么意思 你现在可以通过不精确的泛型 在安全的情况下键入,就像 你可以传递不精确的参数类型 在安全的情况下这样做。

【讨论】:

    【解决方案2】:

    TigerAnimal,所以它可以做任何Animal 可以做的事情。如果我有一个要求Animal 的方法,我也可以传入Tiger

    协方差 - 传递更具体的类型参数

    这是你最熟悉的方向。我可以在任何需要IEnumerable<Animal> 的地方传递IEnumerable<Tiger>


    static void ListAnimals(IEnumerable<Animal> animals)
    {
    }
    
    List<Tiger> tigers = new List<Tiger>();
    ListAnimals(tigers);
    

    逆变 - 传递更一般的类型参数。

    “对立”意味着这“违背”了正常的转换流程。这个比较棘手,因为在你看到它之前它似乎是违反直觉的。

    假设我有一个函数,它期望一个 IComparer&lt;Tiger&gt; 和两只老虎进行比较。逆变说我也可以传入更通用的IComparer&lt;Animal&gt;,因为它可以比较两只老虎(因为老虎是动物)。它以更一般的方式比较它们,但这仍然是类型安全的。


    static void CompareTigers(IComparer<Tiger> comparer, Tiger tiger1, Tiger tiger2)
    {
        comparer.Compare(tiger1, tiger2);
    }
    
    // normal - a tiger comparer can compare two tigers
    IComparer<Tiger> tigerComparer = null;
    CompareTigers(tigerComparer, new Tiger(), new Tiger());
    
    // contravariance - an animal comparer can ALSO compare two tigers
    IComparer<Animal> animalComparer = null;
    CompareTigers(animalComparer, new Tiger(), new Tiger());
    

    请注意,这也适用于委托。我可以将Action&lt;Animal&gt; 传递给需要Action&lt;Tiger&gt; 的函数,因为Tiger 对象也可以安全地传递给Action&lt;Animal&gt; 委托。

    【讨论】:

      【解决方案3】:

      Eric Lippert 在最近的blog post 中提出了一个很好的解释

      【讨论】:

        【解决方案4】:

        以下文章处理与代表的协变和逆变:http://msdn.microsoft.com/en-us/library/ms173174.aspx

        也许它对你有用,即使你还没有进入代理。我发现它很容易理解。

        【讨论】:

          【解决方案5】:

          【讨论】:

            猜你喜欢
            • 2021-09-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多