Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>My understanding is that it is not subtype relationships which are co/contra-variant but rather operations (or projections) between those types (such as delegates and generics). Therefore:</p> <pre><code>Animal someAnimal = new Giraffe(); </code></pre> <p>is not co-variant, but rather this is just assignment compatibility since the type Giraffe is 'smaller than' the type Animal. Co/contra-variance becomes an issue when you have some projection between these types, such as:</p> <pre><code>IEnumerable&lt;Giraffe&gt; giraffes = new[] { new Giraffe(); }; IEnumerable&lt;Animal&gt; animals = giraffes; </code></pre> <p>This is not valid in C#3, however it should be possible since a sequence of giraffes is a sequence of animals. The projection <code>T -&gt; IEnumerable&lt;T&gt;</code> preserves the 'direction' of the type relationship since <code>Giraffe &lt; Animal</code> and <code>IEnumerable&lt;Giraffe&gt; &lt; IEnumerable&lt;Animal&gt;</code> (note that assignment requires that the type of the left-hand side is at least as wide as the right).</p> <p>Contra-variance reverses the type relationship:</p> <pre><code>Action&lt;Animal&gt; printAnimal = a =&gt; {System.Console.WriteLine(a.Name)}; Action&lt;Giraffe&gt; printGiraffe = printAnimal; </code></pre> <p>This is also not legal in C#3, but it should be since any action taking an animal can cope with being passed a Giraffe. However, since <code>Giraffe &lt; Animal</code> and <code>Action&lt;Animal&gt; &lt; Action&lt;Giraffe&gt;</code> the projection has reversed the type relationships. This is legal in C#4.</p> <p>So to answer the questions in your example:</p> <pre><code>//the following are neither covariant or contravariant - since there is no projection this is just assignment compatibility Mammal mammal1 = new Giraffe(); Mammal mammal2 = new Dolphin(); //compare is contravariant with respect to its arguments - //the delegate assignment is legal in C#4 but not in C#3 Func&lt;Mammal, Mammal, bool&gt; compare = (m1, m2) =&gt; //whatever Func&lt;Giraffe, Dolphin, bool&gt; c2 = compare; //always invalid - right hand side must be smaller or equal to left hand side Mammal mammal1 = new Animal(); //not valid for same reason - animal cannot be assigned to Mammal Compare(new Animal(), new Dolphin()); </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload