C# : Is Variance (Covariance / Contravariance) another word for Polymorphism?

前端 未结 5 2022
傲寒
傲寒 2020-11-28 02:39

I am trying to figure out the exact meaning of the words Covariance and Contravariance from several articles online and questions on StackOverflow,

相关标签:
5条回答
  • 2020-11-28 03:14

    I think is is special kind of polymorphism not another word for it. It is polymorphism in delegates where a delegate with a return type of base can accept child type.

    0 讨论(0)
  • 2020-11-28 03:16

    It's certainly related to polymorphism. I wouldn't say they're just "another word" for polymorphism though - they're about very specific situations, where you can treat one type as if it were another type in a certain context.

    For instance, with normal polymorphism you can treat any reference to a Banana as a reference to a Fruit - but that doesn't mean you can substitute Fruit every time you see the type Banana. For example, a List<Banana> can't be treated as a List<Fruit> because list.Add(new Apple()) is valid for List<Fruit> but not for List<Banana>.

    Covariance allows a "bigger" (less specific) type to be substituted in an API where the original type is only used in an "output" position (e.g. as a return value). Contravariance allows a "smaller" (more specific) type to be substituted in an API where the original type is only used in an "input" position.

    It's hard to go into all the details in a single SO post (although hopefully someone else will do a better job than this!). Eric Lippert has an excellent series of blog posts about it.

    0 讨论(0)
  • 2020-11-28 03:21

    I found this collection:

    Covariance and Contravariance in C#, Part One

    Covariance and Contravariance in C#, Part Two: Array Covariance

    Covariance and Contravariance in C#, Part Three: Member Group Conversion Variance

    Covariance and Contravariance in C#, Part Four: Real Delegate Variance

    Covariance and Contravariance In C#, Part Five: Higher Order Functions Hurt My Brain

    Covariance and Contravariance in C#, Part Six: Interface Variance

    Covariance and Contravariance in C# Part Seven: Why Do We Need A Syntax At All?

    Covariance and Contravariance in C#, Part Eight: Syntax Options

    Covariance and Contravariance in C#, Part Nine: Breaking Changes

    Covariance and Contravariance in C#, Part Ten: Dealing With Ambiguity

    Covariance and Contravariance, Part Eleven: To infinity, but not beyond

    0 讨论(0)
  • 2020-11-28 03:25

    Thanks for all the shout-outs, guys.

    Jon and Rasmus's answers are fine, I would just add a quick technical note.

    When speaking casually and informally, yes, people use "covariance" and "contravariance" to refer to a specific kind of polymorphism. That is, the kind of polymorphism where you treat a sequence of spiders as though it were a sequence of animals.

    Were we to get all computer-sciency and try to make more technical definitions, then I probably would not say that covariance and contravariance are "a kind of polymorphism". I would approach a more technical definition like this:

    First, I'd note that there are two possible kinds of polymorphism in C# that you might be talking about, and it is important to not confuse them.

    The first kind is traditionally called "ad hoc polymorphism", and that's the polymorphism where you have a method M(Animal x), and you pass spiders and giraffes and wallabies to it, and the method uniformly treats its passed-in arguments the same way by using the commonalities guaranteed by the Animal base class.

    The second kind is traditionally called "parametric polymorphism", or "generic polymorphism". That's the ability to make a generic method M<T>(T t) and then have a bunch of code in the method that again, treats the argument uniformly based on commonalities guaranteed by the constraints on T.

    I think you're talking about the first kind of polymorphism. But my point is just that we can define polymorphism as the ability of a programming language to treat different things uniformly based on a known commonality. (For example, a known base type, or known implemented interface.)

    Covariance and contravariance is the ability of a programming language to take advantage of commonalities between generic types deduced from known commonalities of their type arguments.

    0 讨论(0)
  • 2020-11-28 03:30

    You can think about co- and contravariance as being an advanced form of polymorphism. Not only can you use a child-class as if it was its parent-class, with co- and contravariance, the polymorphism extends to classes that relates to the polymorphic classes.

    Imagine two classes:

    public class Pet { /*...*/ }
    public class Cat:Pet { /*...*/ }
    

    Polymorphism is being able to use a Cat as a Pet:

    void Feed(Pet pet) { /* ... */ }
    
    Cat cat = ...
    Feed(cat);
    

    Co- and contravariance is used to talk about being able to use an ICollection<Cat> as an ICollection<Pet> (covariance):

    void FeedAll(ICollection<Pet> pets) { /* ... */ }
    
    List<Cat> cats = ...
    FeedAll(cats);
    

    or to use an Action<Pet> as an Action<Cat> (contravariance):

    Action<Pet> GetFeeder() { /* ... */ }
    
    Action<Cat> feeder = GetFeeder();
    

    Eric Lippert wrote a great blog series about it when they were first designing the feature. Part one is here.

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