更新时间:2022-12-16 08:36:09
你把协变和逆变弄错了.让我们考虑 Action<object>
和 Action<string>
.删除实际的泛型,您正在尝试执行以下操作:
You've got the covariance and contravariance the wrong way round. Let's consider Action<object>
and Action<string>
. Removing the actual generics, you're trying to do something like this:
private Action<object> _foo;
public void Foo(Action<string> bar)
{
// This won't compile...
_foo = bar;
}
现在假设我们接着写:
_foo(new Button());
这很好,因为 Action<object>
可以被传递 any 对象...但是我们已经用一个 必须 的委托对其进行了初始化> 接受一个字符串参数.哎哟.
That's fine, because Action<object>
can be passed any object... but we've initialized it with a delegate which must take a string argument. Ouch.
这不是类型安全的,因此无法编译.
This isn't type safe, so doesn't compile.
不过, 的另一种方式也可以:
The other way would work though:
private Action<string> _foo;
public void Foo(Action<object> bar)
{
// This is fine...
_foo = bar;
}
现在当我们调用 _foo
时,我们必须 传入一个字符串 - 但这很好,因为我们已经用一个可以接受任何 object
引用作为参数,所以我们可以给它一个字符串.
Now when we invoke _foo
, we have to pass in a string - but that's fine, because we've initialized it with a delegate which can take any object
reference as a parameter, so it's fine that we happen to be giving it a string.
所以基本上 Action<T>
是 逆变 - 而 Func
So basically Action<T>
is contravariant - whereas Func<T>
is covariant:
Func<string> bar = ...;
Func<object> foo = bar; // This is fine
object x = foo(); // This is guaranteed to be okay
不清楚你想用这个动作做什么,所以很遗憾,我无法就如何解决这个问题提供任何建议......
It's not clear what you're trying to do with the action, so unfortunately I can't really give any advice on how to get around this...