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

.net 2.0 アセンブリで実行peverifyしたところ、次のメッセージが表示されました。

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) ...

ドキュメントには、アンマネージ コードから呼び出されるように設計されていると書かれていますが、インターフェイスであることの副作用として、安定した (仮想) メソッドを呼び出すことができます。

peverify2.0、4.0どちらを対象としても動作することを確認しております。

于 2011-08-03T03:05:09.560 に答える