为什么 C# 不能隐式转换 Action<T> Where T : BaseType to Action<BaseType>

Why C# cannot cast implicitly an Action<T> Where T : BaseType to Action<BaseType>

我尝试将 Action 转换为约束类型。为什么 C# 不能转换它?

如果我强制转换 return 为 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;
}

并非每个 Action<TModel> 都是 Action<BaseObject>。让我们看一个具体的例子:Action<string>Action<object>.

Action<object> 委托可以将任何 object 引用作为参数。写 action(new object()).

是完全有效的

现在想想 Action<string> - 它 只能 引用 string。您显然希望以下代码能够编译 - 您希望它在执行时表现如何?

Action<string> printLength = text => Console.WriteLine(text.Length);
Action<object> action = printLength; // This isn't actually valid
action(new object());

基本上,Action<T>T中是逆变,而不是协变。所以 Action<object>Action<string> 的隐式转换,但反之则不然。

将其应用于您的具体情况,假设我有:

Action<DerivedObject1> x = do1 => Console.WriteLine(do1.SomeProperty);
SetMyAction<DerivedObject1>(x);

// Presumably there's *something* to invoke the action...
InvokeMyAction(new DerivedObject2());

你希望发生什么?