这是个虫子吗?访问以0为参数的专用静态方法时出现MissingMethodException
本文关键字:专用 参数 静态方法 MissingMethodException 访问 | 更新日期: 2023-09-27 18:20:31
我不确定是否应该在这里问这个问题,但现在我们开始了,在单元测试一个参数为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;
}
}
以下是我测试代码的方式:
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
在第一次调用中,我得到了预期的结果,在第二次调用中我得到了异常(我将强制转换添加到short中,认为异常可能是因为它没有找到一个以int为参数的方法)。
有人能再现这种行为吗?,我做错什么了吗?
谢谢你的帮助。
问题是这个方法有两个重载(还有其他重载,但它们在这里无关紧要):
public Object InvokeStatic(string name, params Object[] args)
public Object InvokeStatic(string name, BindingFlags invokeAttr, params Object[] args)
不同之处在于,第二过载具有类型为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 })
除了在代码中没有将文本0
传递给方法之外,您可以先进行强制转换。根据规范,在这种情况下不应选择BindingFlags
过载。但像这样的错误是一个已知的错误,不会被修复,因为它会破坏一些正在运行的程序。
有趣。。。我能够复制它,我找到了修复它的方法
short s = 0;
var actual2 = (NotificationResult)privateHelperType.InvokeStatic(
"GetExecuteResult", s);
我会尽量让你的类不密封。这纯粹是猜测,但可能是将NotificationContext子类化为PrivateType的一部分。
我的第二个建议是下载类似dotpeek的东西:http://blogs.jetbrains.com/dotnet/2011/05/free-net-decompiler-is-available-for-early-access/看看PrivateType是什么样子的。了解它是如何运作的将有助于弄清实际发生了什么。