可能是重复的,但是我找不到合适的方式来表达自己想要的东西。
是否可以使用属性本身或扩展名来获取属性返回的支持字段的名称?
private string VariableNameToGet;
public string TheProperty {get => VariableNameToGet; set {VariableNameToGet = value;}}
换句话说,是否有一种方法可以像TheProperty.GetPrivateVariableName()
那样以通用方式返回"VariableNameToGet"
呢?
答案 0 :(得分:1)
您可以使用 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,但我从未尝试过。