19

帮帮我 - 为什么这段代码在 .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;
}

peverify在 .net 2.0 程序集上运行并收到以下消息:

ImageResizer.Util.Utils::parseEnum[T]][offset 0x0000000A] 调用的'this'参数必须是调用方法的'this'参数。

VerificationException: Operation could destabilize the runtime在中等信任下运行代码时,这会导致一条消息。

我已经阅读了所有关于堆栈溢出的类似帖子,但没有一篇适用于这段代码。

泛型是否有一些新的东西会导致这段代码在某种程度上无效?

4

1 回答 1

32

错误的根本原因是 IsEnum 的签名发生了变化。

在 .NET 2.0(和 3.0)中,IsEnum不是虚拟方法

public bool IsEnum { get; }

发出来调用它的程序集是:

call instance bool [mscorlib]System.Type::get_IsEnum()

在 .NET 4.0 中,IsEnum是一个虚拟方法

public virtual bool IsEnum { get; }

这是 4.0 的相同装配线:

callvirt instance bool [mscorlib]System.Type::get_IsEnum()

您收到的错误是在 2.0 版本之前添加到 peverify 中的,并在以非虚拟方式调用虚拟方法时发出警告。

现在,peverify加载您的代码,加载 .NET 4.0,然后检查您的代码。由于您的代码以非虚拟方式调用 (.NET 4.0) 虚拟方法,因此会显示错误。

有人会认为,既然您是针对 .NET 2.0 版本构建的,这应该没问题,它会加载 .NET 2.0 CLR 进行检查。似乎并非如此。

编辑:

为了检查这一点,我下载了.NET 2.0 的 SDK并在其中进行了尝试peverify。它正确地验证了代码。

所以消息似乎是这样的:使用peverify与代码的目标框架匹配的 a 。

解决方案:

_Type界面似乎为此提供了解决方案:

if (((_Type)typeof(T)).IsEnum) ...

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

我已经确认它适用于peverify您的目标是 2.0 还是 4.0。

于 2011-08-03T03:05:09.560 回答