簡體   English   中英

獲取屬性的支持字段名稱

[英]Getting backing field name of a property

可能是重復的,但我找不到一種方法來正確制定我正在尋找的內容。

有沒有辦法使用屬性本身或擴展來獲取屬性返回的支持字段的名稱?

private string VariableNameToGet;
public string TheProperty {get => VariableNameToGet; set {VariableNameToGet = value;}}

換句話說,是否有一種方法可以得到像TheProperty.GetPrivateVariableName()這樣的東西,它會以通用的方式返回"VariableNameToGet"

您可以使用Module.ResolveMember方法獲取字段信息

假設我們需要獲取System.ComponentModel.BrowsableAttribute.Browsable的支持字段

// get property info
PropertyInfo property = typeof(BrowsableAttribute).GetProperty("Browsabe");

// Need getter, because setter is missing
MethodInfo getter = property.GetGetMethod();

// Now we should get MSIL bytes stream that represents operations
byte[] bytes = getter.GetMethodBody().GetILAsByteArray();

/* IL looks like this
IL_0000: ldarg.0
IL_0001: ldfld bool System.ComponentModel.BrowsableAttribute::'<Browsable>k__BackingField'
IL_0006: ret
*/

// Knowing that field token is Int32 and it's located at offset=2 we can get it
int fieldReference = BitConvert.ToInt32(bytes, 2);

// Last part is to get actual FieldInfo
var field = (FieldInfo)property.DeclaringType.Module.ResolveMember(fieldReference);

// Now we have access to field's backing field!
Console.WriteLine(field.Name);

此解決方案遠非完美:它假設屬性由 Roslyn 編譯器生成並使用自動實現的屬性。 如果有人手動實現了屬性,我們可能會崩潰,因為代碼大小應該是 7。可能會在運行時的未來版本中中斷或在以前的版本中不起作用(我已經在 net5 上測試過)

更好的解決方案是使用 Mono.Cecil,但我從未嘗試過。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM