为什么C#无法隐式转换为Action <t>其中T:BaseType to Action <basetype>

时间:2016-04-12 09:15:56

标签: generics casting delegates action

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

如果我强制转换,则返回为空

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;
}

1 个答案:

答案 0 :(得分:3)

并非每个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>在<{1}}中是逆变,而不是协变。所以TAction<object>的隐式转换,但反之亦然。

将其应用于您的具体案例,假设我有:

Action<string>

您期望发生什么?