2013-01-03 65 views
2

我在這裏看了一下cecil的問題,我還沒有看到有關這個問題的任何內容。如何使用mono.cecil按類型在方法體中查找變量?

我所試圖實現的是找到method.Body.Variables一個變量,(在我的情況System.Exception)是一種特定類型的

我寫了下面的代碼以爲它會做的伎倆:

var exceptionTypeReference = module.Import(typeof(Exception)); 
var exceptionVariable = method.Body.Variables.First(x => x.VariableType == exceptioinTypeReference); 

即使我確信原因是我對cecil的noobness是在運行時出現「Sequence contains no matching elements」錯誤,但我對此似乎很陌生。

我已經通過了代碼,我知道這裏有一個變量,它的類型是System.Exception,但它不想匹配exceptionTypeReference

我確定這很簡單,我的大腦從學習塞西爾的腦子裏炸了出來。即使如此,任何指針,用溼魚等在臉上sma would,都會非常感激。

回答

4

每次導入一個類型它是TypeReference

所以這

var typeReference1 = moduleDefinition.Import(typeof (Exception)); 
var typeReference2 = moduleDefinition.Import(typeof (Exception)); 
Debug.WriteLine(typeReference1 == typeReference2); 

將輸出false不同的實例時。

所以,當你正在做的查詢

  • VariableType可能是TypeReference代表Exception
  • exceptionTypeReference將是TypeReference代表Exception

實例的實例,但它們是不一樣的參考,TypeReference沒有建立平等檢查。

你需要做的是

var exceptionType = module.Import(typeof(Exception)); 
var exceptionVariable = method 
       .Body 
       .Variables 
       .First(x => x.VariableType.FullName == exceptionType.FullName); 

還記得你必須處理繼承的異常類型。

作爲一方不要小心使用.Import(typeof (Exception))。原因是它爲您提供了當前代碼的Exception類型,而不是目標程序集的Exception類型。例如,您可能正在使用.net4程序集處理WinRT程序集。導入.net4異常類型可能會給你一些奇怪的行爲。

所以你也一樣的安全做這個

var exceptionVariable = method 
        .Body 
        .Variables 
        .First(x => x.VariableType.FullName == "System.Exception"); 
+0

謝謝@Simon。我確實想過使用'FullName'屬性,但(愚蠢地)認爲會有更好的方法...我會用它來代替。我沒有意識到您描述的異常行爲。你會有一些閱讀材料(用於研究目的)嗎? –

相關問題