0

我有 c# 应用程序。我有 2 个不同的类(Step1.StateStep2.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);

UserStateUpdate方法有 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调用正确的方法,但是当应用程序移动到使用Step2.State表示状态的 Step2 时。它引发以下异常。请注意,当我在调用重载方法之前检查curState中存储的内容(类型为动态)时,我看到的是类型为Step2.State的正确状态。

'BI4A.Agent.Agent.UserStateUpdate(BI4A.IMDP.IAction, BI4A.Step1.State, System.Speech.Recognition.RecognitionResult)' 的最佳重载方法匹配有一些无效参数

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

4

1 回答 1

1

艾伦,

问题不在于 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。当我用 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

另外,请参阅stackoverflow条目 传递动态参数在从继承接口调用方法时抛出RuntimeBinderException

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

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

我希望这有帮助。

于 2013-09-08T02:28:42.567 回答