Understanding Covariance and Contravariance in C# 4.0

前端 未结 5 1465
臣服心动
臣服心动 2020-12-02 21:17

I watched a video about it on Channel 9 but I didn\'t really understand it much.

Can someone please give me a simple example about these that\'s easy to understand?

相关标签:
5条回答
  • 2020-12-02 21:45

    Eric Lippert came up with a very good explanation in a recent blog post

    0 讨论(0)
  • 2020-12-02 21:51

    A Tiger IS an Animal so it can do anything an Animal can do. If I have a method that asks for an Animal I can also pass in a Tiger.

    Covariance - Passing a more specific type argument

    This is the direction you are most familiar with. I can pass an IEnumerable<Tiger> anywhere that expects an IEnumerable<Animal>.


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

    Contravariance - Passing a more general type argument.

    The 'contra' implies that this goes 'against' the normal conversion flow . This one is trickier because it seem's counter-intuitive until you see it in action.

    Say I have a function which expects an IComparer<Tiger> and two tigers to be compared. Contravariance says I can also pass in the more general IComparer<Animal> because it can also compare two tigers (since a Tiger IS an animal). It compares them in a more general way, but this is still type safe.


    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());
    

    Note that this also works with delegates. I can pass an Action<Animal> into a function that expects an Action<Tiger> because Tiger objects can also be passed safely to the Action<Animal> delegate.

    0 讨论(0)
  • 2020-12-02 21:54

    The following article deals with co- and contravariance with delegates: http://msdn.microsoft.com/en-us/library/ms173174.aspx.

    Perhaps it is useful to you, even if you're not into delegates yet. I found it to be quite easy to understand.

    0 讨论(0)
  • 2020-12-02 21:59

    You may want to look at this blog, he does a fantastic job of explaining it, but I think it will take more examples to clear it up for people, as this gets into a very hard-to-understand area, but, the quote below from the article sums it up well.

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

    "covariance and contravariance" means that you can now pass inexact generic types when it's safe to do so, just as you can pass inexact argument types when it's safe to do so.

    0 讨论(0)
  • 2020-12-02 22:03

    MSDN docs for C# 4.0 (and VB) are here: Covariance and Contravariance

    If you are interested in concrete examples, they are here:

    • Using Variance in Interfaces for Generic Collections

    • Using Variance in Delegates

    • Using Variance for Func and Action Generic Delegates

    0 讨论(0)
提交回复
热议问题