2016-05-03 54 views
0

比方說,我們有一些類人最終消費:如何獲取方法中引用的所有屬性?

public class SampleClass 
{ 
    [Obsolete("This property was slain in Moria", false)] 
    public double SampleProperty { get; set; } 

    [Obsolete("This method was slain in Moria", false)] 
    public static void SampleMethod() 
    { 
    } 
} 

然後讓說,有人會消耗它:

public static double SampleConsumer() 
{ 
    SampleClass.SampleMethod(); 
    var classy = new SampleClass(); 
    return classy.SampleProperty; 
} 

我試圖確定內SampleConsumer過時的方法和屬性的所有引用。

我想通了如何獲取方法,這要歸功於Kris's response to this question.總之,看起來像:

public static void GetMethodReferences(MethodDefinition method) 
{ 
    foreach (var instruction in method.Body.Instructions) 
    { 
     if (instruction.OpCode == OpCodes.Call) 
     { 
      MethodReference methodCall = instruction.Operand as MethodReference; 
      // ... 

其中methodCall.CustomAttributes將包含我們希望檢測到過時的屬性。

我想完成類似的屬性引用。


我迄今爲止嘗試:

注意,在CIL的classy.SamplePropertycallvirt指令表示:

System.Double FoobarNamespace.SampleClass::get_SampleProperty() 

我試過,包括在GetMethodReferencesOpCodes.Callvirt,但唯一屬性虛擬get方法似乎有一個CompilerGeneratedAttribute(沒有過時的屬性)。

接下來我決定偷看虛擬get方法。迭代的虛方法的說明書,發現有一個ldfld OA d˚FLD)指令:

System.Double FoobarNamespace.SampleClass::<SampleProperty>k__BackingField  

我試圖檢查其陳舊的屬性:

// for each instruction in the virtual get_SampeProperty() 
    if (instruction.OpCode == OpCodes.Ldfld) 
    { 
     var fieldDefinition = instruction.Operand as MethodDefinition; 
     // check fieldDefinition.Attributes 
     // check fieldDefinition.CustomAttributes 
     // but neither of them have the Obsolete attribute 
     // ... 

我認爲我實際需要做的是獲得PropertyDefinitionPropertyReferenceSampleProperty,但我似乎無法弄清楚如何在消費者方法的背景下做到這一點。

想法?

+0

爲什麼你不只是看着編譯器的警告。編譯器已經爲你處理了所有這些。 – Servy

+0

你需要它代碼嗎?我的意思是,如果你使用VS2015,它已經給你提供了這個信息,如果你去了這個功能,你會有一條線告訴你參考的數量,如果你點擊它,它會爲你帶來一個帶有所有呼叫的鏡頭,其他VS版本,你可以去函數名稱和「查找所有引用」 – Gusman

+0

@Servy我們有外部開發人員使用我們的API。他們中的一些人已經忽略了VS編譯器的警告一段時間,所以我們想給他們一個工具來運行一個大的[已編譯]代碼庫來檢測他們是否使用任何過時的方法。 將來,他們將能夠將應用程序上傳到我們的平臺上,並且我們希望上傳過程在他們嘗試上傳消耗過時端點的應用程序時拒絕/警告他們(即,它需要在代碼中 - - 在VS的上下文之外)。 – scholtes

回答

0

在IL中,對於方法沒有屬性的概念,只有屬性方法的概念。我認爲塞西爾反映了這一點,所以你不能從MethodDefinitionPropertyDefinition,但你可以反過來做。

的代碼可能看起來像(未經測試):

MethodDefinition method; 

PropertyDefinition property = method.DeclaringType.Properties 
    .SingleOrDefault(p => p.GetMethod == method || p.SetMethod == method); 

請記住,這是理論上的可能是一個單一的方法都屬於多個屬性,但我不認爲任何理智的編譯器會這麼做。

相關問題