You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中Newtonsoft.Json反序列化继承类型报错的排查与解决

问题分析与解决方案

问题原因

这个报错确实和Newtonsoft.Json对继承类型的默认处理逻辑有关。默认情况下,JSON.NET不会在序列化时写入派生类型的元数据,反序列化抽象基类Entity时,无法直接实例化抽象类,导致生成的UnitEntity实例为null,最终在初始化Dictionary<string, UnitEntity>时因为传入null集合触发Value cannot be null. Parameter name: collection错误。

而转为Dictionary<string, object>时,JSON.NET会用JObject存储反序列化结果,直接调用JToken.Value方法时因为未指定具体类型,才会出现方法未实现的提示。

解决方案

方案1:启用类型元数据保留(TypeNameHandling)

通过配置TypeNameHandling,让JSON.NET在序列化时写入类型信息,反序列化时根据元数据识别派生类型,正确实例化对象。

序列化代码(修改原有序列化逻辑)

var serializeSettings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto, // 自动为派生类型添加类型元数据
    Formatting = Formatting.Indented // 可选,格式化JSON便于阅读
};

// 假设yourDictionary是要序列化的Dictionary<string, UnitEntity>实例
string jsonContent = JsonConvert.SerializeObject(yourDictionary, serializeSettings);
File.WriteAllText(filePath, jsonContent);

反序列化代码

var deserializeSettings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
    // 安全提示:如果担心类型注入风险,可限制允许的类型,例如自定义SerializationBinder
};

string factionEntityJson = File.ReadAllText(filePath);
Dictionary<string, UnitEntity> entity = JsonConvert.DeserializeObject<Dictionary<string, UnitEntity>>(factionEntityJson, deserializeSettings);

方案2:自定义JsonConverter(无需类型元数据)

如果不想在JSON中写入类型元数据,可自定义转换器,强制将基类Entity反序列化为UnitEntity实例(适用于确定基类只有这一种派生类的场景)。

自定义转换器代码

public class EntityToUnitConverter : JsonConverter<Entity>
{
    public override Entity ReadJson(JsonReader reader, Type objectType, Entity existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 直接反序列化为UnitEntity
        return serializer.Deserialize<UnitEntity>(reader);
    }

    public override void WriteJson(JsonWriter writer, Entity value, JsonSerializer serializer)
    {
        // 序列化时按UnitEntity处理
        serializer.Serialize(writer, value as UnitEntity);
    }
}

使用转换器的序列化/反序列化代码

// 序列化
var settings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new EntityToUnitConverter() },
    Formatting = Formatting.Indented
};
string jsonContent = JsonConvert.SerializeObject(yourDictionary, settings);
File.WriteAllText(filePath, jsonContent);

// 反序列化
string factionEntityJson = File.ReadAllText(filePath);
Dictionary<string, UnitEntity> entity = JsonConvert.DeserializeObject<Dictionary<string, UnitEntity>>(factionEntityJson, settings);

额外检查项

  • 确保Entity和UnitEntity类有公共无参构造函数,如果使用私有构造函数,需为其添加[JsonConstructor]特性,让JSON.NET可以调用。
  • 检查类中是否有未公开的字段/属性,或者循环引用(可通过配置ReferenceLoopHandling.Ignore解决循环引用问题)。

内容的提问来源于stack exchange,提问作者NeoKuro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 18:11:08