[英]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.