将动态强制转换的实例传递给重载方法 c#

本文关键字:重载 方法 实例 动态 转换 | 更新日期: 2023-09-27 18:30:42

我有c#应用程序。我有 2 个不同的类(Step1.State 和 Step2.State)(它们实现了称为 IMDP 的相同接口。IState),它表示我的应用程序执行的 2 个不同步骤中的应用程序状态。我有 2 个重载方法来更新应用程序状态。

我的方法之一中有以下代码:

Step1.State s1s = null;
Step2.State s2s = null;

然后,我根据其类型转换当前状态。currentState 是作为参数接收的已实现接口的实例。首先,我将其存储在动态类型中。

  //currentState is instance of IMDP.IState interface which is 
  //implemented by the two states
    dynamic curState=currentState;  
            if(curState is Step1.State)
            {
                s1s = (Step1.State)currentState;
                curState = s1s;
            }
            else if (curState is Step2.State)
            {
                s2as = (Step2.State)currentState;
                curState = s2s;
            }

然后我在同一方法中调用我的重载方法。

  currentState = myAgent.UserStateUpdate(prevAction, curState, e.Result);

用户状态更新方法有 2 个重载版本。第一个获取 Step1.State,第二个获取 Step2.State 作为区分参数。喜欢下面;

IMDP.IState UserStateUpdate(IMDP.IAction act, Step1.State st, RecogResult rr)
IMDP.IState UserStateUpdate(Step2.Abuse.Action act, Step2.State st, RecogResult rr)

应用程序调用 Step1.State 的正确方法,但当应用程序移动到步骤 2 时,它使用 Step2.State 进行状态表示。它会引发以下异常。请注意,当我在调用重载方法之前检查curState(动态类型)中存储的内容时,我看到一个正确的状态,该状态类型为Step2.State

"BI4A 的最佳重载方法匹配。Agent.Agent.UserStateUpdate(BI4A.IMDP。IAction, BI4A.步骤1.状态,系统.语音.识别.识别结果)'有一些无效的参数"

这基本上表明系统尝试调用接受Step1.State而不是Step2.State的重载方法。我不知道,如何让它调用正确的方法。感谢您的任何帮助。

将动态强制转换的实例传递给重载方法 c#

艾伦,

问题不在于 State 参数。我已经用下面给出的代码验证了这一点:

class Program
{
    interface IState
    {
    }
    class State1 : IState
    {
    }
    class State2 : IState
    {
    }
    private static void UpdateState(State1 s1)
    {
        Console.WriteLine("State1 Updated.");
    }
    private static void UpdateState(State2 s1)
    {
        Console.WriteLine("State2 Updated.");
    }
    static void Main(string[] args)
    {
        var random = new Random(123456);
        var i = 10;
        while (i-- > 0)
        {
            var n = random.Next();
            dynamic curStep = (n % 2) == 0 ? (dynamic)new State1() : new State2();
            UpdateState(curStep);
        }
        Console.ReadKey();
    }
}

但是,问题似乎是由于第一个参数中的类型不匹配,即IMDP。IAction 和 Step2.Abuse.Action.当我使用操作参数修改上面的代码时,我遇到了同样的错误。修改后的代码如下:

class Program
{
    interface IState
    {
    }
    class State1 : IState
    {
    }
    class State2 : IState
    {
    }
    interface IAction
    {
    }
    class SomeAction : IAction
    {
    }
    private static void UpdateState(IAction act, State1 s1)
    {
        Console.WriteLine("State1 IAction Updated.");
    }
    private static void UpdateState(SomeAction act, State2 s1)
    {
        Console.WriteLine("State2 SomeAction Updated.");
    }
    static void Main(string[] args)
    {
        var random = new Random(123456);
        var i = 10;
        IAction act = new SomeAction();
        while (i-- > 0)
        {
            var n = random.Next();
            dynamic curStep = (n % 2) == 0 ? (dynamic)new State1() : new State2();
            UpdateState(act, curStep);
        }
        Console.ReadKey();
    }
}

在网上挖掘后,我遇到了下面的链接,其中提到这是一个已知的错误。https://connect.microsoft.com/VisualStudio/feedback/details/597276/dynamic-runtime-fails-to-find-iset-t-contains-during-runtime

另外,请参阅堆栈溢出条目传递动态参数会在从继承的接口调用方法时引发运行时绑定器异常

建议

的解决方案:我建议您将第二种方法的操作参数类型从Step2.Abuse.Action更改为IMDP。IAction。我知道这不是一个优雅的解决方案,但它有效。若要确保只允许 Step2.Abuse.Action 类型的对象,可以检查对象类型并引发异常,如下所示:

if (!(act is Step2.Abuse.Action))
    throw new Exception('Invalid Action Type.');

我希望这有所帮助。