Interfaces may have variant type parameters.
interface IEnumerable<out T>
{
// ...
}
interface IComparer<in T>
{
// ...
}
but classes and structures may not
class BadClass<in T1, out T2> // not allowed
{
}
struct BadStruct<in T1, out T2> // not allowed
{
}
nor do generic method declarations
class MyClass
{
public T Bad<out T, in T1>(T1 t1) // not allowed
{
// ...
}
}
The example below shows multiple variance declarations on the same interface
interface IFoo<in T1, out T2, T3>
// T1 : Contravariant type
// T2 : Covariant type
// T3 : Invariant type
{
// ...
}
IFoo<Animal, Dog, int> foo1 = /* ... */;
IFoo<Dog, Animal, int> foo2 = foo1;
// IFoo<Animal, Dog, int> is a subtype of IFoo<Dog, Animal, int>