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
interface IConsumer<T> // Noncompliant
{
bool Eat(T fruit);
}
Compliant solution
interface IConsumer<in T>
{
bool Eat(T fruit);
}