I try to cast an Action to is constraint type. Why C# cannot cast It ?
If I force cast the return is null
private Action<BaseObject> MyAction { get; set; }
//Cannot implicitly cast
internal void SetMyAction<TModel>(Action<TModel> action) where TModel : BaseObject
{
MyAction = action;
}
//MyAction return null
internal void SetMyAction<TModel>(Action<TModel> action) where TModel : BaseObject
{
MyAction = (Action<TModel>)action;
}
Not every Action<TModel>
is an Action<BaseObject>
. Let's look at a concrete example: Action<string>
and Action<object>
.
An Action<object>
delegate can take any object
reference as a parameter. It's perfectly valid to write action(new object())
.
Now think about an Action<string>
- it can only take a string
reference. You apparently expect the following code to compile - how would you expect it to behave at execution time?
Action<string> printLength = text => Console.WriteLine(text.Length);
Action<object> action = printLength; // This isn't actually valid
action(new object());
Basically, Action<T>
is contravariant in T
, not covariant. So there is an implicit conversion from Action<object>
to Action<string>
, but not vice versa.
Applying that to your specific case, imagine that I had:
Action<DerivedObject1> x = do1 => Console.WriteLine(do1.SomeProperty);
SetMyAction<DerivedObject1>(x);
// Presumably there's *something* to invoke the action...
InvokeMyAction(new DerivedObject2());
What would you expect to happen?
See more on this question at Stackoverflow