将带有嵌套对象的对象保存到文件的最佳方法?

Best way to save objects with nested objects to a file?

提问人:TheMostEpic 提问时间:1/2/2020 最后编辑:TheMostEpic 更新时间:1/2/2020 访问量:414

问:

我正在开发这个软件,您可以在其中创建 RPG 游戏的派对并将其保存到文件中。有多个对象具有嵌套类,例如 Item 数组中的 contains 对象。我试图通过使用 JSON 序列化英雄来将英雄保存到文件中,但问题是,JSON 不会保存对象的类型,如果我使用 dataFromFile.ToObject<Member> 之类的东西,嵌套对象就不会存在。MemberBagBagItem

将带有嵌套对象的对象保存到文件中的最佳方法是什么,以便轻松将它们加载回来并且所有嵌套对象也都在那里?

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;
        }
    }
C# JSON 文件 对象 保存

评论

1赞 Trevor 1/2/2020
请告诉我们您尝试过什么,哪些不起作用以及预期输出,以便我们进一步为您提供帮助。我们需要能够看到您正在处理的内容,以帮助您找出您的问题,否则对此的答案将是固执己见的,并且可能会也可能不会解决您的问题。
0赞 Jimi 1/2/2020
您使用了什么 JSON 序列化程序?哪里出了问题?序列化程序将对象序列化/反序列化您提供的类模型类型。创建公共属性。bag
1赞 Selvin 1/2/2020
提示:json.net + TypeNameHandling
0赞 TheMostEpic 1/2/2020
如果 Bag 不是公共属性,即使它是 Member 对象中的嵌套对象,它也不会加载吗?
0赞 TheMostEpic 1/2/2020
似乎 TypeNameHandling 是要走的路。谢谢Selvin :)newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm

答:

0赞 TheMostEpic 1/2/2020 #1

似乎 TypeNameHandling 是要走的路。谢谢Selvin :)

newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm