为什么在.NET 4下运行时此行会导致VerificationException?

时间:2011-08-02 23:07:55

标签: c# .net .net-4.0 peverify

帮帮我大家 - 为什么这个代码在.NET 4.0下运行时会导致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]] [offset 0x0000000A]调用的'this'参数必须是调用方法的'this'参数。

在中等信任下运行代码时会出现VerificationException: Operation could destabilize the runtime消息。

我已经阅读了所有关于堆栈溢出的类似帖子,并且它们都不适用于此代码。

是否有一些新的泛型会导致此代码无效?

1 个答案:

答案 0 :(得分:32)

错误的根本原因是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) ...

文档说它设计为从非托管代码调用,但作为一个接口的副作用,它提供了一个稳定的(虚拟)方法来调用。

我已确认无论您定位2.0还是4.0,它都适用于peverify