C# 反思:使用静态对象引用更改 class 的私有字段?
C# Reflection: Changing private fields of a class with static object reference?
我遇到了一个非常具体的案例,我在 Whosebug 上阅读了大量关于设置和获取 classes 的私有字段和属性的问题,但它们似乎都不起作用。
我正在通过使用 Harmony(一个在运行时注入代码的库)注入代码来修改 Unity 游戏。我成功地更改了很多东西,但是一旦值是私有的,我就碰壁了,因为我无法访问或更改这些值。
使用 dnSpy 检查代码时:
所以有 public class World {} 包含字段 public static World inst 以及两个私有字段 private int GridWidth 和 private int GridHeight。
它还包含属性 GridWidth 和 Gridheight,两者都是 public,但只有一个 Getter。它包含在这里无关紧要的其他字段。
World.inst 在 private void Awake() 方法中设置,一个特定的 Unity 方法。
简而言之:
public class World : MonoBehaviour
{
public static World inst;
private void Awake()
{
World.inst = this;
this.gridWidth = 55;
this.gridHeight = 55;
}
private int GridWidth;
private int GridHeight;
public int GridWidth
{
get
{
return this.gridWidth;
}
}
public int GridHeight
{
get
{
return this.gridHeight;
}
}
}
现在我尝试从外部更改 GridWidth 和 GridHeight 的值但失败了。我无法更改这部分代码。
在 dnSpy 中,这两个字段被引用(当鼠标悬停在字段上时)为 World.GridWidth 和 World.GridHeight
但它们明确设置为 World.inst.GridWidth 和 GridHeight.
我当前的代码是
var WorldField = typeof(World).GetField("GridWidth", BindingFlags.Instance | BindingFlags.NonPublic);
WorldField.SetValue(World.inst, 100);
但这不起作用。我还没有真正使用过反射,这可能是我犯了一个非常明显的错误,如果是这样,我很抱歉。
我很困惑,非常感谢任何帮助和深入的解释。
首先,我认为以下是一个打字错误
private int GridWidth;
private int GridHeight;
以上应该是
private int gridWidth;
private int gridHeight;
这是因为您已经有一个同名的 public readonly 属性,它在内部引用私有变量 - gridWidth 和 gridHeight。
现在,要更改变量,您需要使用gridWidth
来引用字段:
var WorldField = typeof(World).GetField("gridWidth", BindingFlags.Instance | BindingFlags.NonPublic);
WorldField.SetValue(World.inst, 100);
我遇到了一个非常具体的案例,我在 Whosebug 上阅读了大量关于设置和获取 classes 的私有字段和属性的问题,但它们似乎都不起作用。
我正在通过使用 Harmony(一个在运行时注入代码的库)注入代码来修改 Unity 游戏。我成功地更改了很多东西,但是一旦值是私有的,我就碰壁了,因为我无法访问或更改这些值。
使用 dnSpy 检查代码时: 所以有 public class World {} 包含字段 public static World inst 以及两个私有字段 private int GridWidth 和 private int GridHeight。 它还包含属性 GridWidth 和 Gridheight,两者都是 public,但只有一个 Getter。它包含在这里无关紧要的其他字段。 World.inst 在 private void Awake() 方法中设置,一个特定的 Unity 方法。
简而言之:
public class World : MonoBehaviour
{
public static World inst;
private void Awake()
{
World.inst = this;
this.gridWidth = 55;
this.gridHeight = 55;
}
private int GridWidth;
private int GridHeight;
public int GridWidth
{
get
{
return this.gridWidth;
}
}
public int GridHeight
{
get
{
return this.gridHeight;
}
}
}
现在我尝试从外部更改 GridWidth 和 GridHeight 的值但失败了。我无法更改这部分代码。
在 dnSpy 中,这两个字段被引用(当鼠标悬停在字段上时)为 World.GridWidth 和 World.GridHeight 但它们明确设置为 World.inst.GridWidth 和 GridHeight.
我当前的代码是
var WorldField = typeof(World).GetField("GridWidth", BindingFlags.Instance | BindingFlags.NonPublic);
WorldField.SetValue(World.inst, 100);
但这不起作用。我还没有真正使用过反射,这可能是我犯了一个非常明显的错误,如果是这样,我很抱歉。
我很困惑,非常感谢任何帮助和深入的解释。
首先,我认为以下是一个打字错误
private int GridWidth;
private int GridHeight;
以上应该是
private int gridWidth;
private int gridHeight;
这是因为您已经有一个同名的 public readonly 属性,它在内部引用私有变量 - gridWidth 和 gridHeight。
现在,要更改变量,您需要使用gridWidth
来引用字段:
var WorldField = typeof(World).GetField("gridWidth", BindingFlags.Instance | BindingFlags.NonPublic);
WorldField.SetValue(World.inst, 100);