Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 286 Vote(s) - 3.43 Average
  • 1
  • 2
  • 3
  • 4
  • 5
<out T> vs <T> in Generics

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

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

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

#2
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).

[To see links please register here]

Reply

#3
"`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>`.
Reply

#4
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][1]

[1]:
Reply

#5
The `out` keyword in generics is used to denote that the type T in the interface is covariant. See [Covariance and contravariance][1] 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][2] 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*.


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#6
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>`.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through