【发布时间】:2020-01-02 15:02:42
【问题描述】:
我正在开发这个软件,您可以在其中创建一个角色扮演游戏的派对并将其保存到一个文件中。有多个 Member 对象具有嵌套类,如 Bag 和 Bag 在 Item 数组中包含 Item 对象。我试图通过用 JSON 序列化英雄来将它们保存到一个文件中,但问题是,JSON 不会保存对象的类型,如果我使用类似 dataFromFile.ToObject<Member> 的东西,嵌套对象将不存在。
将具有嵌套对象的对象保存到文件中以便轻松加载它们并且所有嵌套对象也将在那里的最佳方法是什么?
public class Member
{
public string Name { get; set; }
public string Race { get; set; }
public int CarryingWeight { get; set; }
public int MaxCarryWeight { get; set; }
public int MaxMana { get; set; }
public int MeleeAttack { get; set; }
public int RangeAttack { get; set; }
public int Defense { get; set; }
public int MaxHealth { get; set; }
IBag bag = new LargeBag();
}
public class LargeBag : IBag
{
public int Weight { get; set; } = 7;
IItem[] items = new IItem[12];
}
// I put all kinds of dynamic objects to a Dictionary and Serialized the whole
// Dictionary with JSON, then saved it to a file.
Dictionary<string, dynamic> savedObjects = new Dictionary<string, dynamic>();
savedObjects.Add("hero1", Globals.member1);
savedObjects.Add("hero2", Globals.member2);
var settings = new JsonSerializerSettings() { ContractResolver = new
MyContractResolver() };
var saveData = JsonConvert.SerializeObject(savedObjects, settings);
// When DeSerializing the Dictionary, i'm able to create the Heroes back with
// .ToObject method, but the Bag's stuff aren't there
Dictionary<string, dynamic> loadedObjects = new Dictionary<string, dynamic>();
loadedObjects = JsonConvert.DeserializeObject<Dictionary<string,
dynamic>>(loadData);
Member loadedMember1 = loadedObjects["member1"].ToObject<Member>();
Member loadedMember2 = loadedObjects["member2"].ToObject<Member>();
// JSON settings used
public class MyContractResolver :
Newtonsoft.Json.Serialization.DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type,
MemberSerialization memberSerialization)
{
var props = type.GetProperties(BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance)
.Select(p => base.CreateProperty(p,
memberSerialization))
.Union(type.GetFields(BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance)
.Select(f => base.CreateProperty(f,
memberSerialization)))
.Where(p => !p.PropertyName.Contains("k__BackingField"))
.ToList();
props.ForEach(p => { p.Writable = true; p.Readable = true; });
return props;
}
}
【问题讨论】:
-
请向我们展示您尝试过的内容、无效的内容以及预期的输出,以便我们进一步为您提供帮助。我们需要能够看到您正在使用什么来帮助您找出问题,否则对此的答案将是固执己见的,并且可能会或可能不会解决您的问题。
-
你使用了什么 JSON 序列化器?什么地方出了错?序列化程序将对象从您提供的类模型类型序列化/反序列化到您提供的类模型类型。将
bag设为公共属性。 -
提示:json.net + TypeNameHandling
-
如果 Bag 不是公共属性,即使它是 Member 对象中的嵌套对象,它也不会加载吗?
-
看来 TypeNameHandling 是要走的路。谢谢塞尔文 :) newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm