Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It's probably easiest to give examples - that's certainly how I remember them.</p> <p><strong>Covariance</strong></p> <p>Canonical examples: <code>IEnumerable&lt;out T&gt;</code>, <code>Func&lt;out T&gt;</code></p> <p>You can convert from <code>IEnumerable&lt;string&gt;</code> to <code>IEnumerable&lt;object&gt;</code>, or <code>Func&lt;string&gt;</code> to <code>Func&lt;object&gt;</code>. Values only come <em>out from</em> these objects.</p> <p>It works because if you're only taking values out of the API, and it's going to return something specific (like <code>string</code>), you can treat that returned value as a more general type (like <code>object</code>).</p> <p><strong>Contravariance</strong></p> <p>Canonical examples: <code>IComparer&lt;in T&gt;</code>, <code>Action&lt;in T&gt;</code></p> <p>You can convert from <code>IComparer&lt;object&gt;</code> to <code>IComparer&lt;string&gt;</code>, or <code>Action&lt;object&gt;</code> to <code>Action&lt;string&gt;</code>; values only go <em>into</em> these objects.</p> <p>This time it works because if the API is expecting something general (like <code>object</code>) you can give it something more specific (like <code>string</code>).</p> <p><strong>More generally</strong></p> <p>If you have an interface <code>IFoo&lt;T&gt;</code> it can be covariant in <code>T</code> (i.e. declare it as <code>IFoo&lt;out T&gt;</code> if <code>T</code> is only used in an output position (e.g. a return type) within the interface. It can be contravariant in <code>T</code> (i.e. <code>IFoo&lt;in T&gt;</code>) if <code>T</code> is only used in an input position (e.g. a parameter type).</p> <p>It gets potentially confusing because "output position" isn't quite as simple as it sounds - a parameter of type <code>Action&lt;T&gt;</code> is still only using <code>T</code> in an output position - the contravariance of <code>Action&lt;T&gt;</code> turns it round, if you see what I mean. It's an "output" in that the values can pass from the implementation of the method <em>towards</em> the caller's code, just like a return value can. Usually this sort of thing doesn't come up, fortunately :)</p>
 

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