【问题标题】:Why does this line cause a VerificationException when running under .NET 4?为什么在 .NET 4 下运行时此行会导致 VerificationException?
【发布时间】:2011-08-02 23:07:55
【问题描述】:

帮帮我 - 为什么这段代码在 .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 消息。

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

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

【问题讨论】:

  • 我刚刚运行了这段代码,没有收到这样的异常。你确定这是错误所在吗?这是在asp中使用的吗?
  • 您是使用 Visual Studio 还是其他编译器(如 Mono)生成 .NET 程序集?
  • 该错误消息向我表明它在调用站点(即您调用该方法的位置)有此问题。你能把这段代码也给我们看看吗?
  • 程序集是使用 VS 2010 生成的。以低信任度运行代码以重现错误。下面是一个调用代码的例子:`totalBehavior = parseEnum("sizelimits.totalbehavior", TotalSizeBehavior.ThrowException);
  • 另外,我发现 peverify 只有在方法中出现 if (!typeof(T).IsEnum) 行时才会阻塞。

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


【解决方案1】:

错误的根本原因是 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 接口表示它是“版本无关的”。它可能旨在解决此类问题。我会把它添加到答案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
相关资源
最近更新 更多