错误的根本原因是 IsEnum 签名的更改。
在 .NET 2.0(和 3.0)中,IsEnum不是虚拟方法 http://msdn.microsoft.com/en-us/library/system.type.isenum%28v=VS.80%29.aspx:
public bool IsEnum { get; }
发出的调用它的程序集是:
call instance bool [mscorlib]System.Type::get_IsEnum()
在 .NET 4.0 中,IsEnum是一个虚方法 http://msdn.microsoft.com/en-us/library/system.type.isenum%28v=VS.100%29.aspx:
public virtual bool IsEnum { get; }
这是 4.0 的相同装配线:
callvirt instance bool [mscorlib]System.Type::get_IsEnum()
你得到的错误是在 2.0 版本发布之前添加到 peverify 中 http://www.bluebytesoftware.com/blog/2005/09/22/StaticCallsToVirtualMethodsAndVerifiability.aspx,并在非虚拟调用虚拟方法时发出警告。
Now, peverify
加载您的代码,加载.NET 4.0,然后检查您的代码。由于您的代码以非虚拟方式调用 (.NET 4.0) 虚拟方法,因此会显示错误。
人们可能会认为,既然您是针对 .NET 2.0 版本进行构建,那么这应该没问题,并且它会加载 .NET 2.0 CLR 进行检查。看来并非如此。
Edit:
为了检查这一点,我下载了.NET 2.0的SDK http://www.google.com/search?q=.net+2.0+sdk并尝试了peverify
在那里。它正确验证了代码。
所以消息似乎是这样的:使用peverify
它与您的代码的目标框架相匹配。
解决方案:
看来_Type界面 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices._type.isenum.aspx对此提供了解决方案:
if (((_Type)typeof(T)).IsEnum) ...
文档说它被设计为从非托管代码调用,但作为接口的副作用,它提供了一个稳定的(虚拟)方法来调用。
我已经确认它适用于peverify
无论您的目标是 2.0 还是 4.0。