<out T> vs <T> in Generics

C#GenericsCovariance

C# Problem Overview


What is the difference between <out T> and <T>? For example:

public interface IExample<out T>
{
    ...
}

vs.

public interface IExample<T>
{
    ...
}

C# Solutions


Solution 1 - C#

The out keyword in generics is used to denote that the type T in the interface is covariant. See Covariance and contravariance for details.

The classic example is IEnumerable<out T>. Since IEnumerable<out T> is covariant, you're allowed to do the following:

IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;

The second line above would fail if this wasn't covariant, even though logically it should work, since string derives from object. Before variance in generic interfaces was added to C# and VB.NET (in .NET 4 with VS 2010), this was a compile time error.

After .NET 4, IEnumerable<T> was marked covariant, and became IEnumerable<out T>. Since IEnumerable<out T> only uses the elements within it, and never adds/changes them, it's safe for it to treat an enumerable collection of strings as an enumerable collection of objects, which means it's covariant.

This wouldn't work with a type like IList<T>, since IList<T> has an Add method. Suppose this would be allowed:

IList<string> strings = new List<string>();
IList<object> objects = strings;  // NOTE: Fails at compile time

You could then call:

objects.Add(new Image()); // This should work, since IList<object> should let us add **any** object

This would, of course, fail - so IList<T> can't be marked covariant.

There is also, btw, an option for in - which is used by things like comparison interfaces. IComparer<in T>, for example, works the opposite way. You can use a concrete IComparer<Foo> directly as an IComparer<Bar> if Bar is a subclass of Foo, because the IComparer<in T> interface is contravariant.

Solution 2 - C#

For remembering easily the usage of in and out keyword (also covariance and contravariance), we can image inheritance as wrapping:

String : Object
Bar : Foo

in/out

Solution 3 - C#

consider,

class Fruit {}

class Banana : Fruit {}

interface ICovariantSkinned<out T> {}

interface ISkinned<T> {}

and the functions,

void Peel(ISkinned<Fruit> skinned) { }

void Peel(ICovariantSkinned<Fruit> skinned) { }

The function that accepts ICovariantSkinned<Fruit> will be able to accept ICovariantSkinned<Fruit> or ICovariantSkinned<Banana> because ICovariantSkinned<T> is a covariant interface and Banana is a type of Fruit,

the function that accepts ISkinned<Fruit> will only be able to accept ISkinned<Fruit>.

Solution 4 - C#

"out T" means that type T is "covariant". That restricts T to appear only as a returned (outbound) value in methods of the generic class, interface or method. The implication is that you can cast the type/interface/method to an equivalent with a super-type of T.
E.g. ICovariant<out Dog> can be cast to ICovariant<Animal>.

Solution 5 - C#

From the link you posted....

> For generic type parameters, the out keyword specifies that the type > parameter is covariant.

EDIT: Again, from the link you posted

> For more information, see Covariance and Contravariance (C# and Visual Basic). http://msdn.microsoft.com/en-us/library/ee207183.aspx

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCole TobinView Question on Stackoverflow
Solution 1 - C#Reed CopseyView Answer on Stackoverflow
Solution 2 - C#o0omycomputero0oView Answer on Stackoverflow
Solution 3 - C#JodrellView Answer on Stackoverflow
Solution 4 - C#James WorldView Answer on Stackoverflow
Solution 5 - C#Brad CunninghamView Answer on Stackoverflow