比方說,我們有一些類人最終消費:如何獲取方法中引用的所有屬性?
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.SampleProperty
由callvirt
指令表示:
System.Double FoobarNamespace.SampleClass::get_SampleProperty()
我試過,包括在GetMethodReferences
的OpCodes.Callvirt
,但唯一屬性虛擬get
方法似乎有一個CompilerGeneratedAttribute
(沒有過時的屬性)。
接下來我決定偷看虛擬get
方法。迭代的虛方法的說明書,發現有一個ldfld
(升 OA d˚F即LD)指令:
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
// ...
我認爲我實際需要做的是獲得PropertyDefinition
或PropertyReference
SampleProperty
,但我似乎無法弄清楚如何在消費者方法的背景下做到這一點。
想法?
爲什麼你不只是看着編譯器的警告。編譯器已經爲你處理了所有這些。 – Servy
你需要它代碼嗎?我的意思是,如果你使用VS2015,它已經給你提供了這個信息,如果你去了這個功能,你會有一條線告訴你參考的數量,如果你點擊它,它會爲你帶來一個帶有所有呼叫的鏡頭,其他VS版本,你可以去函數名稱和「查找所有引用」 – Gusman
@Servy我們有外部開發人員使用我們的API。他們中的一些人已經忽略了VS編譯器的警告一段時間,所以我們想給他們一個工具來運行一個大的[已編譯]代碼庫來檢測他們是否使用任何過時的方法。 將來,他們將能夠將應用程序上傳到我們的平臺上,並且我們希望上傳過程在他們嘗試上傳消耗過時端點的應用程序時拒絕/警告他們(即,它需要在代碼中 - - 在VS的上下文之外)。 – scholtes