== Why is this an issue?

In the interests of making code as usable as possible, interfaces and delegates with generic parameters should use the ``++out++`` and ``++in++`` modifiers when possible to make the interfaces and delegates covariant and contravariant, respectively.


The ``++out++`` keyword can be used when the type parameter is used only as a return type in the interface or delegate. Doing so makes the parameter covariant, and allows interface and delegate instances created with a sub-type to be used as instances created with a base type. The most notable example of this is ``++IEnumerable<out T>++``, which allows the assignment of an ``++IEnumerable<string>++`` instance to an ``++IEnumerable<object>++`` variable, for instance.


The ``++in++`` keyword can be used when the type parameter is used only as a method parameter in the interface or a parameter in the delegate. Doing so makes the parameter contravariant, and allows interface and delegate instances created with a base type to be used as instances created with a sub-type. I.e. this is the inversion of covariance. The most notable example of this is the ``++Action<in T>++`` delegate, which allows the assignment of an ``++Action<object>++`` instance to a ``++Action<string>++`` variable, for instance.


=== Noncompliant code example

[source,csharp]
----
interface IConsumer<T>  // Noncompliant
{
    bool Eat(T fruit);
}
----


=== Compliant solution

[source,csharp]
----
interface IConsumer<in T>
{
    bool Eat(T fruit);
}
----


ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Add the "[in|out]" keyword to parameter "X" to make it "[covariant|contravariant]".


'''
== Comments And Links
(visible only on this page)

=== on 8 Jul 2015, 15:17:03 Ann Campbell wrote:
\[~tamas.vajk] note that the description I've written is for the "me" from last week. If it states too much of what is obvious to C# developers, please let me know what should be eliminated.

=== on 20 Jul 2015, 12:20:09 Tamas Vajk wrote:
\[~ann.campbell.2] I think the description is okay. We could shorten it, but it's not necessary. ``++in++`` and ``++out++`` is not used too often, so it's not necessarily common knowledge.


I've modified the description a bit. ``++IComparer++`` is not the most notable example for ``++in++`` generic arguments. We haven't discussed this, but this rule also applies for delegates with generic parameters. And the most notable example for ``++in++`` is the ``++Action++`` delegate: \https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx


A side note: the most notable example of having both ``++in++`` and ``++out++`` is probably the ``++Func<T, TResult>++`` delegate: \https://msdn.microsoft.com/en-us/library/bb549151(v=vs.110).aspx

=== on 20 Jul 2015, 14:09:21 Ann Campbell wrote:
Thanks [~tamas.vajk]. Note that I've just worked covariant/contravariant into the description in the appropriate places. I suddenly realized we described them but didn't actually attach the descriptions to the words!

endif::env-github,rspecator-view[]
