提问人:Apache81 提问时间:10/18/2023 更新时间:10/18/2023 访问量:58
C# 强制转换 Action 泛型
C# casting Action generics
问:
我有我的第一堂课,喜欢
public abstract class A
{
protected event Action<A> onCompleted;
public void CompleteExecution()
{
// doing something...
onCompleted?.Invoke(this);
}
}
还有另一个类,比如
public class B : A
{
private Action<B> _callback;
public void Initialize(Action<B> callback)
{
_callback = callback;
}
public void Execute()
{
onCompleted += (Action<A>)callback;
// doing something specific.
}
}
然后我使用 B 和类似的东西:
public class Executor
{
private B _inst;
public Executor
{
_inst = new B();
_inst.Initialize(Callback);
}
public void Execute()
{
_inst.Execute();
}
public void Finalize()
{
_inst.CompleteExecution();
}
private void Callback(B inst)
{
// completed !!!
}
}
如果参数相关,我以为我可以强制转换 Action,但我在
onCompleted += (Action<A>)callback;
在 B 类的 Execute 方法中。
我通过将该行替换为
onCompleted += _ => callback?.Invoke(this);
但我觉得它很丑陋。
有没有更好的方法来实现演员表?
答:
1赞
JonasH
10/18/2023
#1
有没有更好的方法来实现演员表?
不。 是逆变的,这意味着您可以转换为 .这之所以有效,是因为继承自 ,可以使用 的实例作为参数调用相同的原因。Action<T>
Action<A>
Action<B>
B
A
void MyMethodA(A a)
B
但它不是协变的,所以你不能做相反的事情。出于同样的原因,不能使用 作为参数的实例调用。void MyMethodB(B b)
A
如果您当前的解决方法有效,则可以使用它。您还可以使用泛型执行某些操作,请参阅奇怪的重复模板模式。但请注意,这可能会增加解决方案的复杂性。或者,可以在两个类中声明具有相同名称的事件,并使用 new 修饰符隐藏继承的成员。
评论
Action<A>
并且是两种完全不相关的类型。虽然是-a,但不是-a,因此它们不能只是相互铸造。Action<B>
B
A
Action<B>
Action<A>
EventArgs
A
实例,而不仅仅是 .所以这也是有效的:(假设也派生自 ,但不是 ) 当你的委托类型为 时,它需要 的实例 ,而不是 的实例。Action<A> a = (Action<A>) myBDelegate;
B
a.Invoke(new C())
C
A
B
Action<B>
B
C