2011-08-02 71 views
17

幫我解決問題 - 爲什麼在.NET 4.0下運行時,這段代碼會導致一個VerificationException?爲什麼這行在.NET 4下運行時會導致一個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]] [偏移0X0000000A]的 '這' 參數來該調用必須是調用方法的'this'參數。

這將導致在中等信任下運行代碼時發出VerificationException: Operation could destabilize the runtime消息。

我已經閱讀了堆棧溢出中所有類似的帖子,並且它們都不適用於此代碼。

是否有什麼新的泛型會導致此代碼在某種程度上無效?

+0

我只是運行這個代碼,並沒有收到這樣的例外。你確定這是錯誤所在嗎?這是在asp中使用嗎? –

+0

您是否使用Visual Studio或其他編譯器(如Mono)生成.NET程序集? – Jacob

+1

錯誤消息向我表明它位於正在發生此問題的呼叫地點(即您調用方法的地方)。你能向我們展示那些代碼嗎? –

回答

31

錯誤的根本原因是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。

+4

夢幻般的答案!我喜歡學習這樣的事情。 –

+0

謝謝 - 這是有道理的。我的程序集都是針對.NET 2.0和.NET 4.0框架的,所以我想我根本無法調用IsEnum,對嗎? –

+1

實際上,有一個'_Type'接口說它是「版本無關的」。它可能已被設計爲解決這樣的問題。我會將其添加到答案中。 – porges

相關問題