繁体   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