Search code examples
c#.netgenericscovariancecontravariance

Generic constraint for Action doesn't work as expected


I am having some trouble understanding why the following snippet does not give me an error

public void SomeMethod<T>(T arg) where T : MyInterface
{
  MyInterface e = arg;
}

But this one, which I would expect to work due to the generic type constraint

private readonly IList<Action<MyInterface>> myActionList = new List<Action<MyInterface>>();

public IDisposable Subscribe<T>(Action<T> callback) where T: MyInterface
{
  myActionList.Add(callback); // doesn't compile
  return null
}

Gives this error

cannot convert from 'System.Action<T>' to 'System.Action<MyInterface>'

I am using VS2012 sp1 and .NET 4.5.

Can anyone explain why the constraint does not allow this to compile?


Solution

  • Classes and delegates are not the same thing. System.Action<MyInterface> represents a function with a single parameter of type MyInterface whilst System.Action<T> represents a method with a parameter of type T : MyInterface. The function signatures are not compatible, it is not relevent that T is a derivative of MyInterface, the signature would only be compatible if T was exactly MyInterface.