i got a question here,hope warmheat developer help.
this is the problem i meet:
i want to save a class instance's fields due to reflection,the code below:
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);
}
it works,and the saved json like this:
[
{
"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
}
]
}
]
then when i use it for fill in new class instance's fields,code like this:
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);
}
}
}
}
it cause error:
ArgumentException: Object of type 'System.Double' cannot be converted to type 'System.Single'. System.RuntimeType.CheckValue (System.Object value, System.Reflection.Binder binder, System.Globalization.CultureInfo culture, 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 culture) (at :0) System.Reflection.FieldInfo.SetValue (System.Object obj, System.Object value) (at :0) TestReflectEnum.ApplyFields () (at Assets/Scripts/TestReflectEnum.cs:82)
i think reflect fieldinfo.setvalue need the exactly object type to fill in,so i change code like this:
object obj = Convert.ChangeType(item.ValValue, item.ValType);
finfo.SetValue(this, obj);
but still cause error:
InvalidCastException: Object must implement IConvertible. System.Convert.ChangeType (System.Object value, System.Type conversionType, System.IFormatProvider provider) (at :0) System.Convert.ChangeType (System.Object value, System.Type conversionType) (at :0) TestReflectEnum.ApplyFields () (at Assets/Scripts/TestReflectEnum.cs:82)
now the only way for me is write out all kind of object type condition,and change type object one by one,it's so troublesome way,i hope there is a common function for read object from txt/json,and could setvalue right - -
Aucun commentaire:
Enregistrer un commentaire