为什么在 .NET 4 下运行时此行会导致 VerificationException?
请帮助我 - 为什么此代码在 .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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
错误的根本原因是 IsEnum 签名的更改。
在 .NET 2.0(和 3.0)中,IsEnum 是' t 虚拟方法:
发出来调用它的程序集是:
在 .NET 4.0 中,IsEnum 是一个虚拟方法:
这是同一行4.0 的程序集:
您收到的错误是 添加的在 2.0 版本之前的 peverify 中,并在非虚拟调用虚拟方法时发出警告。
现在,
peverify
加载您的代码,加载 .NET 4.0,然后检查您的代码。由于您的代码以非虚拟方式调用 (.NET 4.0) 虚拟方法,因此会显示错误。人们可能会认为,既然您是针对 .NET 2.0 版本进行构建,那么这应该没问题,并且它会加载 .NET 2.0 CLR 进行检查。看来并非如此。
编辑:
为了检查这一点,我下载了.NET 2.0的SDK 并尝试了其中的
peverify
。它正确验证了代码。因此,消息似乎是这样的:使用与代码的目标框架匹配的
peverify
。解决方案:
似乎
_Type
接口为此提供了一个解决方案:文档说它被设计为从非托管代码调用,但作为接口的副作用,它提供了一个稳定的(虚拟)方法来调用。
我已经确认,无论您的目标是 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:
The assembly emitted to call it is:
In .NET 4.0, IsEnum is a virtual method:
Here is the same line of assembly for 4.0:
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: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.