获取带有反射的实例时如何包含值?

How to include values when getting an instance with reflection?

我正在自动化如何在 Unity 中将具有 [Serializable] 属性的 class 序列化为 Json。

我试图通过 反射 获取 FieldInfo 并将该值传递以将其解析为 Json ,但它失败了。 输出空花括号。

问题代码

public static class SerializeHelper
{
  public static void SerializeObjectField()
  {
    var fieldsInfo = GameInfo.Instance.GetType().GetFields(
    BindingFlags.Public | BindingFlags.Instance);

    foreach (var fieldInfo in fieldsInfo)
    {
      ToJson(fieldInfo);
    }
  }

  private static void ToJson(FieldInfo fieldInfo)
  {
    var json = JsonUtility.ToJson(fieldInfo, true);
    Debug.Log(json); // Empty curly braces are output
  }
}
public class GameInfo : MonoBehaviour
{
  // Sigleton Pattern

  public Gold gold = new();
  public int Gold
  {
    get => gold.Amount;
    set => gold.Amount = value;
  }

  // ...
}
[Serializable]
public class Gold
{
  [SerializeField] private int amount;
  public int Amount
  {
    get => amount;
    set => amount = value;
  }
}

如果我不使用反射手动编写它,它输出就好了。

正确的代码

// ...

var json = JsonUtility.ToJson(GameInfo.Instance.gold, true);
Debug.Log(json);

// ...

输出

{
    "amount": 43 // Create a button that increments by 1 for every click
}

你能告诉我我在使用反射时做错了什么吗?

您错过了一个调用,属性 信息为您提供了一个 field/property 的描述,它与 class 定义相关,但没有引用您的实际实例。

要实际获取您需要在 属性 信息

上调用 GetValue 方法的值

尝试替换

 var json = JsonUtility.ToJson(fieldInfo, true);

类似于:

 var json = JsonUtility.ToJson(fieldInfo.GetValue(instanceReference), true);

下面的工作示例:

public class ReflectionTest : MonoBehaviour
{
    [System.Serializable]
    public class TestClass 
    {
        public string myString = "test";
    }
    public TestClass testClassInstance = new TestClass();

    void OnValidate()
    {
        var fieldInfo = this.GetType().GetField("testClassInstance");
        var value = fieldInfo.GetValue(this);
        var valueString = JsonUtility.ToJson(value);
        Debug.Log($"after serialization {valueString}");
    }

}