如何在 C# 中将 Action<BaseType> 添加到 Action<DerivedType>

问题描述

在 C# 8 中,我可以直接将带有 MethodName(BaseType obj) 签名的方法添加Action<DerivedType> 的 Action 委托。但我无法将 Action<BaseType> 的 Action 委托添加Action<DerivedType> 的委托。

示例:

public class Test
{
    private ActionHandler actionHandler;

    static void Main(string[] args)
    {
        actionHandler = new ActionHandler();

        // Add Delegates Directly

        actionHandler.derivedAction1 += BaseMethod;
        actionHandler.derivedAction1?.Invoke(new DerivedClass1());

        // Add Delegate using Register Method

        actionHandler.Register(ActionType.Derived1,BaseMethod);
        actionHandler.derivedAction1?.Invoke(new DerivedClass1());
    }


    public void BaseMethod(BaseClass myObj)
    {
        if (myObj is DerivedClass1)
            Debug.Log("Method called with Derived1Class object");
        else if (myObj is DerivedClass2)
            Debug.Log("Method called with Derived2Class object");
    }
}

public class ActionHandler
{
    public Action<DerivedClass1> derivedAction1;
    public Action<DerivedClass2> derivedAction2;

    public void Register(ActionType actionType,Action<BaseClass> callback)
    {
        switch (actionType)
        {
            case ActionType.Derived1:
                derivedAction1 += callback; // ERROR HERE
                break;
            case ActionType.Derived2:
                derivedAction2 += callback;
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(actionType),actionType,null);
        }
    }
}

public enum ActionType
{
    Derived1,Derived2
}

public abstract class BaseClass
{
}

public class DerivedClass1 : BaseClass
{
}

public class DerivedClass2 : BaseClass
{
}

输出为:

使用 Derived1Class 对象调用方法

ArgumentException:不兼容的委托类型。首先是 System.Action1[[DerivedClass1,Scripts,Version=0.0.0.0,Culture=neutral,PublicKeyToken=null]] second is System.Action1[[BaseClass,PublicKeyToken=null]]。

值得注意的是,没有编译错误。只有运行时错误

错误来自 Delegate.cs 代码的这一部分:

public static Delegate Combine(Delegate a,Delegate b)
{
      if ((object) a == null)
        return b;
      if ((object) b == null)
        return a;
      return !(a.GetType() != b.GetType()) ? a.CombineImpl(b) : throw new ArgumentException(Locale.GetText("Incompatible Delegate Types. First is {0} second is {1}.",(object) a.GetType().FullName,(object) b.GetType().FullName));
}

a.GetType() != b.GetType() 比较中,我的 actionHandler.derivedAction1 += BaseMethod; 代码b 显示Action<DerivedClass1>,即使该方法具有签名 BaseMethod(BaseClass myObj)。但我的 derivedAction1 += callback; 代码b 显示Action<BaseClass>

我想让 Register 方法起作用。帮助?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)