21

I've just saw an unfamiliar syntax while looking for GroupBy return type:

public interface IGrouping<out TKey, out TElement> : IEnumerable<TElement>

MSDN Source

I know what does out mean in methods, but not in a generics interface.

What does out mean in a generic type?

gdoron
  • 147,333
  • 58
  • 291
  • 367

4 Answers4

18

It denotes a covariant parameter. See also the description on MSDN. Essentially it says, that IGrouping<Aderived, Bderived> can be regarded as IGrouping<Abase, Bbase>, hence you can

IGrouping<Aderived, Bderived> gr = MakeGrouping(...);
IGrouping<Abase, Bbase> grBase = gr;

if Aderived is an interface or a type derived from Abase. This is a feature that comes in handy when you want to call a method that requires a parameter of type IGrouping<Abase, Bbase>, but you only got an object of type IGrouping<Aderived, Bderived>. In this case, both types can be considered equivalent due to the covariance of their type parameters.

Frank
  • 2,738
  • 19
  • 30
8

It is one of the two generic modifiers introduces in C# 4.0 (Visual Studio 2010).

It signifies that the generic parameter it is declared on is covariant.

The in modifier signifies the generic parameter it is declared on is contravariant.

See out (Generic Modifier) and in (Generic Modifier) on MSDN.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • I know the terms [contravariance and covariance](http://msdn.microsoft.com/en-us/library/ee207183.aspx), but the MSDN examples aren't describing the `in` and `out` modifiers for Generics very clear in my opinion. Can you give some examples which are easier to understand? – Matt Dec 14 '12 at 09:47
  • 1
    This is nothing but copy/paste from MSDN. Frank's answer should have been accepted, not this. – Sergey Akopov Feb 21 '13 at 20:06
  • @SergeyAkopov - You are certainly entitled to your opinion, but accepting or not is entirely something that the question asker decides. – Oded Feb 21 '13 at 20:07
5

out just means that the type is only used for output e.g.

public interface Foo<out T>
{
   T Bar()
}

There also is a modifier in that means that the type is only used for input e.g.

public interface Foo<in T>
{
    int Bar(T x)
}

These are used because Interfaces with in are covariant in T and Interfaces with out are contravariant in T.

Ral Zarek
  • 1,058
  • 4
  • 18
  • 25
4

out keyword in this context would indicate the corresponding type parameter to be covariant simply speaking - covariance enables you to use a more derived type than that specified by the generic parameter.

BTW, see this ten part series from Eric Lippert to understand more about covariance and contra-variance: http://blogs.msdn.com/b/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx

VinayC
  • 47,395
  • 5
  • 59
  • 72
  • 1
    The link above is broken: Eric's article can now be found at: https://ericlippert.com/2007/10/16/covariance-and-contravariance-in-c-part-1/ – paytools-steve Mar 24 '23 at 15:49