.NET 4.0 introduced covariance and contravariance of generic types. Here's what this means.
Covariance
The Out
keyword here indicates that the type is covariant. A covariant type T(Of D)
can be cast to a type T(Of B)
where D derives from B. This is possible when the type T(Of D)
only ever uses D values as output (hence the word Out).
For example, the IEnumerable(Of Out T)
interface is covariant because none of its methods accepts any parameters of type T
. Therefore, an IEnumerable(Of String)
can be cast as an IEnumerable(Of Object)
-- if it provides enumerable access to strings, then it provides enumerable access to objects (since strings are objects).
Contravariance
Conversely, the In
keyword may be applied to a type that is eligible for contravariance. A contravariant type T(Of B)
can be cast to a type T(Of D)
where D derives from B. This is possible when the type T(Of B)
only uses B values as input (hence the word In). In other words, contravariance is the exact opposite of covariance.
A good example of a contravariant type would be the IComparer(Of In T)
interface. This interface provides no methods that return T
values; therefore an IComparer(Of Object)
could be cast as an IComparer(Of String)
-- after all, if it can compare objects, it can compare strings.