Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>Now, to my untrained eye, covariance seems to be the same as upcasting, except that it refers the casting of collections. (And of a similar statement can be made regarding contravariance and downcasting).</p> <p>Is it really that simple?</p> </blockquote> <p>Covariance isn't about upcasting, although I can see why you think it's related.</p> <p>Covariance is about the following very simple idea. Let's say you have a variable <code>derivedSequence</code> of type <code>IEnumerable&lt;Derived&gt;</code>. Let's say you have a variable <code>baseSequence</code> of type <code>IEnumerable&lt;Base&gt;</code>. Here, <code>Derived</code> derives from <code>Base</code>. Then, with covariance, the following is a legal assignment, and an implicit reference conversion occurs:</p> <pre><code>baseSequence = derivedSequence; </code></pre> <p>Note that this is not upcasting. It is not the case that <code>IEnumerable&lt;Derived&gt;</code> derives from <code>IEnumerable&lt;Base&gt;</code>. Rather, it is covariance that allows you to assign the value of the variable <code>derivedSequence</code> to the variable <code>baseSequence</code>. The idea is that variables of type <code>Base</code> can be assigned from objects of type <code>Derived</code>, and since <code>IEnumerable&lt;T&gt;</code> is covariant in its parameter, objects of type <code>IEnumerable&lt;Derived&gt;</code> can be assigned to variables of type <code>IEnumerable&lt;Base&gt;</code>.</p> <p>Of course, I haven't yet really explained what covariance is. In general, covariance is about the following simple idea. Let's say you have a mapping <code>F</code> from types to types (I'll denote this mapping by <code>F&lt;T&gt;</code>; given a type <code>T</code> its image under the mapping <code>F</code> is <code>F&lt;T&gt;</code>.) Let's say that this mapping has the following very special property:</p> <blockquote> <p>if <code>X</code> is assignment compatible with <code>Y</code>, then <code>F&lt;X&gt;</code> is assignment compatible with <code>F&lt;Y&gt;</code> as well.</p> </blockquote> <p>In this case, we say that <code>F</code> is covariant in its parameter <code>T</code>. (Here, to say that "<code>A</code> is assignment compatible with <code>B</code>" where <code>A</code> and <code>B</code> are reference types means that instances of <code>B</code> can be stored in variables of type <code>A</code>.)</p> <p>In our case, <code>IEnumerable&lt;T&gt;</code> in C# 4.0, an implicit reference conversion from instances of <code>IEnumerable&lt;Derived&gt;</code> to <code>IEnumerable&lt;Base&gt;</code> if <code>Derived</code> is derived from <code>Base</code>. The direction of assignment compatibility is preserved, and this is why we say that <code>IEnumerable&lt;T&gt;</code> is covariant in its type parameter.</p>
    singulars
    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. 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