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

C# 在.NET 4下运行时,为什么此行会导致VerificationException?,c#,.net,.net-4.0,peverify,C#,.net,.net 4.0,Peverify,各位,帮我一个忙-为什么这段代码在.NET4.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");

各位,帮我一个忙-为什么这段代码在.NET4.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;
}
public T parseEnum(字符串值,T defaultValue){
//删除以下行可以修复此问题
如果(!typeof(T).IsEnum)抛出新的ArgumentException(“T必须是枚举类型”);
返回默认值;
}
我在.net 2.0程序集上运行了
peverify
,并收到以下消息:

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

这会导致
VerificationException:在中等信任下运行代码时,操作可能会破坏运行时消息的稳定性

我已经阅读了所有关于堆栈溢出的类似文章,但没有一篇适用于此代码


泛型中是否有新的东西会导致此代码以某种方式无效?

错误的根本原因是IsEnum的签名发生了更改

在.NET 2.0(和3.0)中,IsEnum:

发出调用它的程序集是:

call instance bool [mscorlib]System.Type::get_IsEnum()
在.NET 4.0中,IsEnum:

以下是4.0的相同装配线:

callvirt instance bool [mscorlib]System.Type::get_IsEnum()
您得到的错误是,并在非虚拟方法被调用时发出警告

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

有人会认为,由于您是根据.NET2.0版本进行构建的,所以这应该没问题,并且它会加载.NET2.0CLR进行检查。似乎不是这样

编辑:

为了检查这一点,我下载并尝试了
peverify
。它正确地验证了代码

因此,信息似乎是这样的:使用与代码目标框架匹配的
peverify

解决方案:

这似乎提供了一个解决方案:

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


我已经确认它可以与
peverify
一起工作,无论您的目标是2.0还是4.0。

我刚刚运行了这段代码,没有收到这样的异常。你确定这就是错误所在吗?这是否在asp中使用?是否使用Visual Studio或其他编译器(如Mono)生成.NET程序集?错误消息向我指出,出现此问题的是调用站点(即调用方法的位置)。你能给我们看一下这些代码吗?程序集是用VS2010生成的。以低信任度运行代码以再现错误。下面是一个调用代码的示例:`totalBehavior=parseEnum(“sizelimits.totalBehavior”,TotalSizeBehavior.ThroweException);另外,我发现
peverify
仅当方法中存在行
if(!typeof(T).IsEnum)
时才会阻塞。谢谢-这很有意义。我的程序集同时面向.NET 2.0和.NET 4.0框架,所以我想我根本不能调用IsEnum,对吗?实际上,有一个
\u Type
接口,它说它是“版本独立的”。它可能被设计用来解决这样的问题。我将把它添加到答案中。
callvirt instance bool [mscorlib]System.Type::get_IsEnum()
if (((_Type)typeof(T)).IsEnum) ...