I have an interface IGenericOrder
as follows:
using System;
using System.Linq.Expressions;
namespace MyNamespace
{
interface IGenericOrder<T> where T : new()
{
Func<T, int> GetStatement(string name);
}
public class GenericOrder<T> : IGenericOrder<T> where T : new()
{
public Func<T, int> GetStatement(string name)
{
return (T) => 4;
}
}
}
Now when I create an instance of that class and cast it back to IGenericOrder<object>
var sorter = (IGenericOrder<object>) new GenericOrder<Foo>();
I get Exception:
InvalidCastException: The instance of type
GenericOrder<Foo>
cannot be cast toIGenericOrder<object>
Which seems clear as the Interface IGenericOrder
is not covariant. However if I make the interface covariant (interface IGenericOrder<out T>
) I get a compiler-error:
Invalid variance: The type parameter 'T' must be contravariantly valid on
IGenericOrder<T>.GetStatement(string)
. 'T' is covariant.
As I read from here covariance can only used when
[the generic type parameter] is used only as a method return type and is not used as a type of formal method parameters.
Does this mean I cannot use co-/contravariance for methods that themselfes return generic instances?
I am using .Net 4.5
T
. If you were allowed to cast the interface toIGenericOrder<object>
, it would return a function that takes an argument of typeobject
. Not allT
s are alsoobject
s - you broke type safety. On the other hand, you can makeT
contra-variant - it's valid to pass a descendant instead of a parent class as an argument. – Luaan