为什么 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());
你希望发生什么?
我尝试将 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());
你希望发生什么?