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

Setting a property {get;} using reflection in C#

我在第 3 方库中有一个 class,只有 get; 属性。

public class Person
{
    public string Name {get;}
}

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

private string m_name;

或者是这样的:

public string Name {get; private set;}

我该如何设置?

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

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

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

否则,您将不得不像这样反汇编 getter 的 MethodInfo 的 IL:

var instructions = yourProp.GetGetMethod().GetInstructions();

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

Ldarg0
Ldfld    (Backing Field)
Ret

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

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;
}

否则,属性 可能是计算出来的,没有支持字段。