I often forget if i have to use in or out when defining covarient and contravarient generic types. In java i have the mnemonic PECS (producer extends consumer super) to help me. Do you know a similar mnemonic for c#?
Asked
Active
Viewed 508 times
3

Marc Gravell
- 1,026,079
- 266
- 2,566
- 2,900

mR_fr0g
- 8,462
- 7
- 39
- 54
-
4RELB - Read Eric Lippert's Blog http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/ – JaredPar Aug 27 '10 at 16:15
-
I infrequently define genetics, except when attempting to create 12 foot lizardmen, everybody like's lizardmen. – Jimmy Hoffa Aug 27 '10 at 16:21
-
@Jimmy Hoffa - yah but anything over 10 feet is just overkill. – Joel Etherton Aug 27 '10 at 16:31
-
@Joel Etherton: They're lizardmen, overkill is the point – Jimmy Hoffa Aug 27 '10 at 16:35
-
1Isn't it fairly easy to know when to use each, since `in` means the interface is taking something in, and `out` means it is giving something out? I can never remember which is which of co- and contra-variance, but the usage of `in` and `out` is never a problem. – Lasse V. Karlsen Aug 27 '10 at 17:38
3 Answers
3
Didn't they do this for us when they called them 'in' and 'out' rather than covariant and contravariant? Just think: am I pushing values 'in', or getting them 'out'? If unsure, try 'out' - it is far more common (and easier to understand).

LBushkin
- 129,300
- 32
- 216
- 265

Marc Gravell
- 1,026,079
- 266
- 2,566
- 2,900
1
in
types are passed in
to functions; out
types are returned out
from functions.

Gabe
- 84,912
- 12
- 139
- 238
-
This is not what mR_fr0g has asked for. He wants a mnemonic for in and out when used as generic class variance type modifiers (which is a new funcionality of C# 4.0), not the common, old usage on method parameters. – rsenna Aug 27 '10 at 19:10
-
rsenna: That's exactly what rsenna asked for. When creating a generic interface, types that are only passed in to functions can get the `in` label and types that are only returned from functions can get the `out` label. Types that are both passed in and returned (or used as `ref` or `out` parameters) are invariant and can't get either label. – Gabe Aug 27 '10 at 19:36
0
When I don't remember, I always refer to IEnumerable<out T>
(which means of course I have to remember the signature of that interface...). You can only get instances of T "out" of an IEnumerable<out T>
, so it is covariant. If you can only pass instances of T "in" to an interface (or delegate, which is more common), it's contravariant.

Thomas Levesque
- 286,951
- 70
- 623
- 758