在 C# 中使用反射设置属性 {get;}

Vah*_*hid 3 .net c# reflection properties backing-field

我在第 3 方图书馆有一门课,只有一个get;财产。

public class Person
{
    public string Name {get;}
}
Run Code Online (Sandbox Code Playgroud)

我想Name使用反射或任何其他合适的方法设置属性,但我不知道 Name 从何处获取其值。我的意思是我不知道它是否有这样的支持字段?

private string m_name;
Run Code Online (Sandbox Code Playgroud)

或者是这样的:

public string Name {get; private set;}
Run Code Online (Sandbox Code Playgroud)

我该如何设置?

Mr *_*son 5

您需要获取FieldInfo属性的支持字段的实例并调用该SetValue()方法。

Mono.Reflection库(在包管理器中可用)将帮助您找到支持字段。

如果属性是自动属性,则可以GetBackingField()PropertyInfo实例上调用扩展方法。

否则,您必须MethodInfo像这样反汇编getter的 IL :

var instructions = yourProp.GetGetMethod().GetInstructions();
Run Code Online (Sandbox Code Playgroud)

这将为您提供该方法的 IL 指令列表。如果它们看起来像这样:

Ldarg0
Ldfld    (Backing Field)
Ret
Run Code Online (Sandbox Code Playgroud)

然后第二条指令将为您提供支持字段。在代码中:

if (instructions.Count == 3 && instructions[0].OpCode == OpCodes.Ldarg_0 && instructions[1].OpCode == OpCodes.Ldfld && instructions[2].OpCode == OpCodes.Ret)
{
    FieldInfo backingField = (FieldInfo)instructions[1].Operand;
}
Run Code Online (Sandbox Code Playgroud)

否则,该属性可能已计算并且没有支持字段。