这是一个错误吗?MissingMethodException访问私有静态方法,参数为0

Jua*_*dio 6 c# .net-4.0 visual-studio-2010

我不确定我是否应该在这里问这个但是我们去了,而单元测试一个私有静态方法,其参数为short我只有在这个参数为0时才会得到一个MissingMethodException.

我正在使用针对Framework 4的VS 2010 SP1(完整版),这里是重现此错误的最小代码(我们正在升级VB6代码,所以不要粗鲁):

    [DataContract]
  public enum NotificationResult
  {
    [EnumMember]
    Success,
    [EnumMember]
    StoredError,
    [EnumMember]
    InvalidId,
    [EnumMember]
    OperationError,
  }

    public sealed class NotificationContext
  {
    private static NotificationResult GetExecuteResult(short result)
    {
      NotificationResult executeResult;
      switch (result)
      {
        case 0:
          executeResult = NotificationResult.Success;
          break;
        case 1:
          executeResult = NotificationResult.StoredError;
          break;
        case 2:
          executeResult = NotificationResult.InvalidId;
          break;
        default:
          executeResult = NotificationResult.OperationError;
          break;
      }

      return executeResult;
    }
  }
Run Code Online (Sandbox Code Playgroud)

以下是我测试代码的方法:

 PrivateType privateHelperType = new PrivateType(typeof(NotificationContext));
      var actual = (NotificationResult)privateHelperType.InvokeStatic(
        "GetExecuteResult", (short)1);
      var actual2 = (NotificationResult)privateHelperType.InvokeStatic(
        "GetExecuteResult", (short)0); //here is where i get the exception
Run Code Online (Sandbox Code Playgroud)

在第一次调用中,我获得了预期的结果,在第二次调用中,我得到了异常(我添加了转换为简短的思考,可能是异常,因为它没有找到一个以int作为参数的方法).

有人能够重现这种行为吗?我做错了吗?

谢谢你的帮助.

svi*_*ick 8

问题是这个方法有两个重载(还有其他的,但它们在这里并不重要):

区别在于第二个重载具有类型的参数BindingFlags,即enum.当你将文字0作为第二个参数传递时,选择了这个重载,因为文字0可以隐式转换为任何文件enum而不使用params被认为比在重载决策中使用它更好.所以,基本上

  • privateType.InvokeStatic("GetExecuteResult", 1) 编译成 privateType.InvokeStatic("GetExecuteResult", new object[] { 1 })
  • privateType.InvokeStatic("GetExecuteResult", 0) 编译成 privateType.InvokeStatic("GetExecuteResult", 0, new object[] { })

这是导致问题的原因.我认为最简单的避免方法是显式创建数组:

privateType.InvokeStatic("GetExecuteResult", new object[] { 0 })
Run Code Online (Sandbox Code Playgroud)

除非在您的代码中没有将文字传递0给方法,否则先将其强制转换.根据规范,BindingFlags在这种情况下不应选择过载.但是像这样的错误是一个已知的错误,不会修复,因为它会破坏一些工作程序.