0

我在这里有一个问题,希望warmheat开发人员提供帮助。

这是我遇到的问题:

由于反射,我想保存类实例的字段,代码如下:

private void SaveFields()
{
    fieldItemList.Clear();
    FieldInfo[] fields = GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
    for (int i = 0; i < fields.Length; i++)
    {
        FieldInfo finfo = fields[i];
        FieldItem item = new FieldItem()
        {
            ValName = finfo.Name,
            ValType = finfo.FieldType,
            ValValue = finfo.GetValue(this),
        };
        fieldItemList.Add(item);
    }
    string json = JsonModule.GetInstance().Serialize(fieldItemList);
    json = JsonModule.GetInstance().FormatJsonString(json);
    Debug.LogFormat("json = {0}", json);
    File.WriteAllText(@"E:\GithubRepo\ShaderSamples\ShaderSamples\fields.json", json);
}

它可以工作,保存的 json 是这样的:

[
{
    "ValName": "fVar",
    "ValType": "System.Single, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
    "ValValue": 2.0
},
{
    "ValName": "iVar",
    "ValType": "System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
    "ValValue": 1
},
{
    "ValName": "Gears",
    "ValType": "GearParam[], Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
    "ValValue": [
        {
            "Vec3": {
                "x": 1.0,
                "y": 2.0,
                "z": 3.0
            },
            "Vec2": {
                "x": 1.0,
                "y": 2.0
            },
            "FVar": 1.0,
            "IVar": 2
        }
    ]
}

]

然后当我用它来填写新类实例的字段时,代码如下:

private void ApplyFields()
{
    string json = File.ReadAllText(@"E:\GithubRepo\ShaderSamples\ShaderSamples\fields.json");
    fieldItemList = JsonModule.GetInstance().Deserialize<List<FieldItem>>(json);
    Debug.LogFormat("fieldItemList = {0}", fieldItemList.Count);
    FieldInfo[] fields = GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
    for (int i = 0; i < fields.Length; i++)
    {
        FieldInfo finfo = fields[i];
        for (int k = 0; k < fieldItemList.Count; k++)
        {
            FieldItem item = fieldItemList[k];
            if (finfo.Name == item.ValName)
            {
                finfo.SetValue(this, item.ValValue);
            }
        }
    }
}

它导致错误:

ArgumentException:“System.Double”类型的对象无法转换为“System.Single”类型。System.RuntimeType.CheckValue (System.Object value, System.Reflection.Binder binder, System.Globalization.CultureInfoculture, System.Reflection.BindingFlags invokeAttr) (at :0) System.Reflection.MonoField.SetValue (System.Object obj, System.Object val,System.Reflection.BindingFlags invokeAttr,System.Reflection.Binder binder,System.Globalization.CultureInfo 文化)(在:0) System.Reflection.FieldInfo.SetValue(System.Object obj,System.Object 值)(在 :0) TestReflectEnum.ApplyFields () (在 Assets/Scripts/TestReflectEnum.cs:82)

我认为反映 fieldinfo.setvalue 需要填写确切的对象类型,所以我更改代码如下:

object obj = Convert.ChangeType(item.ValValue, item.ValType);
finfo.SetValue(this, obj);

但仍然会导致错误:

InvalidCastException:对象必须实现 IConvertible。System.Convert.ChangeType(System.Object 值,System.Type conversionType,System.IFormatProvider 提供程序)(在:0) System.Convert.ChangeType(System.Object 值,System.Type 转换类型)(在:0)TestReflectEnum.ApplyFields () (在资产/脚本/TestReflectEnum.cs:82)

现在对我来说唯一的方法就是写出各种对象类型条件,并逐个更改类型对象,太麻烦了,我希望有一个从txt / json读取对象的通用功能,并且可以正确设置值 - -

4

0 回答 0