我有一个公共(public)静态类Settings,我在其中存储一些公共(public)静态字段:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Reflection;
namespace testApp {
public static class Settings {
public static int appWidth = 800;
public static int appHeight = 600;
public static int layotCols = 1;
public static int layotRows = 1;
public static string TestString = "test";
public static double TestFloat = 1.4;
public static string[] TestStringArray = new[] { "1", "ee", "rrr"};
public static List<string> TestStringArray1 = new List<string>() { "1", "2"};
public static Dictionary<string,string> TestStringArray2 = new Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } };
}
}
现在我想将所有字段保存到文件中,但能够添加新字段,而无需“手动”保存和读取它们。
我决定使用我的动态和反射技能,将所有字段列出到 ExpandoObject,然后列出到 JObject,然后将 File.WriteAllText 列出到“settings.ini”... 难以置信,但它适用于 Newtonsoft.Json 可以序列化的所有字段类型:
public static void saveSettings() {
Type type = typeof(Settings); // Settings is static class with static properties
dynamic dObject = new ExpandoObject();
var exObject = dObject as IDictionary<String, object>;
foreach(var setting in type.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)) {
exObject[setting.Name] = Convert.ChangeType(setting.GetValue(null), setting.FieldType);
}
JObject obj = new JObject();
obj = JObject.FromObject(dObject);
File.WriteAllText("settings.ini", obj.ToString());
}
但是现在我在阅读这个文本文件时遇到了一些麻烦。 我使用了标准的反射方法,只能读取几种数据类型,但数组和其他数据类型:
public static void loadSettings() {
var settingsFile = File.ReadAllText("settings.ini");
JObject obj = JObject.Parse(settingsFile);
Type type = typeof(Settings);
foreach(var setting in type.GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)) {
if(obj[setting.Name]?.ToString() != null) {
setting.SetValue(setting, Convert.ChangeType(obj[setting.Name],setting.FieldType));
}
}
}
我发现,Newtonsoft.Json 还可以使用 JsonConvert.DeserializeObject(object) 反序列化对象并将其转换为多种类型。我尝试过:
setting.SetValue(setting, JsonConvert.DeserializeObject<setting.FieldType>(obj[setting.Name].ToString()));
但是它给出了编译错误...你能帮我吗?
最佳答案
您想要使用重载 JsonConvert.DeserializeObject(String, Type)
:
setting.SetValue(setting, JsonConvert.DeserializeObject(obj[setting.Name].ToString(), setting.FieldType));
或者,您可以使用 JToken.ToObject(Type)
并避免不必要的字符串转换:
setting.SetValue(setting, obj[setting.Name].ToObject(setting.FieldType));
并且,由于 FieldInfo.SetValue(Object, Object)
的第一个 Object
参数静态方法会被忽略,为了清楚起见,您可能只想传递 null:
setting.SetValue(null, obj[setting.Name].ToObject(setting.FieldType));
样本fiddle .
关于c# - 在 C# 中的静态类中使用 JsonConvert.DeserializeObject<T> 进行动态转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40376315/