为什么这行在.NET 4下运行时会导致一个VerificationException?
帮我解决问题 - 为什么在.NET 4.0下运行时,这段代码会导致一个VerificationException?为什么这行在.NET 4下运行时会导致一个VerificationException?
public T parseEnum<T>(string value, T defaultValue) {
//Removing the following lines fixes the problem
if (!typeof(T).IsEnum) throw new ArgumentException("T must be an enumerated type");
return defaultValue;
}
我在.NET 2.0组件跑peverify
并得到以下信息:
ImageResizer.Util.Utils :: parseEnum [T]] [偏移0X0000000A]的 '这' 参数来该调用必须是调用方法的'this'参数。
这将导致在中等信任下运行代码时发出VerificationException: Operation could destabilize the runtime
消息。
我已经阅读了堆栈溢出中所有类似的帖子,并且它们都不适用于此代码。
是否有什么新的泛型会导致此代码在某种程度上无效?
错误的根本原因是IsEnum签名的变化。
在.NET 2.0(和3.0),IsEnum wasn't a virtual method:
public bool IsEnum { get; }
发出调用它的组件是:
call instance bool [mscorlib]System.Type::get_IsEnum()
在.NET 4.0,IsEnum is a virtual method:
public virtual bool IsEnum { get; }
这里是4.0的组装线:
callvirt instance bool [mscorlib]System.Type::get_IsEnum()
您遇到的错误是added in peverify just before the 2.0 release,并且在虚拟方法被称为非虚拟方法时发出警告。
现在,peverify
加载您的代码,加载.NET 4.0,然后检查您的代码。由于您的代码非虚拟调用(.NET 4.0)虚拟方法,因此会显示错误。
有人会认为,因为你正在构建对.NET 2.0版本,这应该没问题,它会加载.NET 2.0 CLR来检查。它似乎并不如此。
编辑:
为了检验这一点,我下载.NET 2.0's SDK,并在那里尝试peverify
。它正确验证了代码。
所以消息看起来是这样的:使用一个peverify
它匹配您的代码的目标框架。
解决方案:
看来,_Type
interface提供了一个解决这个:
if (((_Type)typeof(T)).IsEnum) ...
的文件说,它的设计是从非托管代码调用,但它的副作用作为一个接口,它提供了一个稳定的(虚拟)方法来调用。
我确定它可以与peverify
一起使用,无论您的目标是2.0还是4.0。
梦幻般的答案!我喜欢学习这样的事情。 –
谢谢 - 这是有道理的。我的程序集都是针对.NET 2.0和.NET 4.0框架的,所以我想我根本无法调用IsEnum,对吗? –
实际上,有一个'_Type'接口说它是“版本无关的”。它可能已被设计为解决这样的问题。我会将其添加到答案中。 – porges
我只是运行这个代码,并没有收到这样的例外。你确定这是错误所在吗?这是在asp中使用吗? –
您是否使用Visual Studio或其他编译器(如Mono)生成.NET程序集? – Jacob
错误消息向我表明它位于正在发生此问题的呼叫地点(即您调用方法的地方)。你能向我们展示那些代码吗? –