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

发布于 2024-11-27 17:55:22 字数 674 浏览 7 评论 0原文

请帮助我 - 为什么此代码在 .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 might destabilize the runtime 消息。

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

泛型中是否有新的东西会导致此代码在某种程度上无效?

Help me out folks - why does this code cause a VerificationException when run under .NET 4.0?

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;
}

I ran peverify on the .net 2.0 assembly and got the following message:

ImageResizer.Util.Utils::parseEnum[T]][offset 0x0000000A] The 'this' parameter to the call must be the calling method's 'this' parameter.

This causes a VerificationException: Operation could destabilize the runtime message when running the code under medium trust.

I've already read all the similar-looking posts on stack overflow, and none of them apply to this code.

Is there something new with generics that would cause this code to be somehow invalid?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮生未歇 2024-12-04 17:55:22

错误的根本原因是 IsEnum 签名的更改。

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

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

解决方案:

似乎_Type接口为此提供了一个解决方案:

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

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

我已经确认,无论您的目标是 2.0 还是 4.0,它都可以与 peverify 配合使用。

The underlying reason for the error is a change in the signature of IsEnum.

In .NET 2.0 (and 3.0), IsEnum wasn't a virtual method:

public bool IsEnum { get; }

The assembly emitted to call it is:

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

In .NET 4.0, IsEnum is a virtual method:

public virtual bool IsEnum { get; }

Here is the same line of assembly for 4.0:

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

The error you're getting was added in peverify just before the 2.0 release, and warns when a virtual method is called non-virtually.

Now, peverify loads up your code, loads .NET 4.0, and then checks your code. Since your code calls the (.NET 4.0) virtual method non-virtually, the error is shown.

One would think that since you're building against the .NET 2.0 version, this should be fine, and it would load the .NET 2.0 CLR to check. It doesn't seem so.

Edit:

In order to check this, I downloaded .NET 2.0's SDK and tried the peverify in there. It correctly verifies the code.

So the message would seem to be this: use a peverify which matches the target framework of your code.

Solution:

It seems that the _Type interface provides a solution to this:

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

The documentation says it is designed to be called from unmanaged code, but as a side effect of it being an interface, it provides a stable (virtual) method to call.

I have confirmed that it works with peverify whether you target 2.0 or 4.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文