Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# JSON.NET';s反序列化器';s转换器选择不是多态的(使用声明的类型,而不是实际类型)_C#_Json_Serialization_Json.net - Fatal编程技术网

C# JSON.NET';s反序列化器';s转换器选择不是多态的(使用声明的类型,而不是实际类型)

C# JSON.NET';s反序列化器';s转换器选择不是多态的(使用声明的类型,而不是实际类型),c#,json,serialization,json.net,C#,Json,Serialization,Json.net,我正在使用Json.NET并将TypeNameHandling设置为Object或All。当反序列化程序为对象选择转换器时,我发现它将声明的对象类型传递给每个JsonConverter的CanConvert,而不是实际类型(如对象的$type节点所述) 如果我为实现公共接口的不同类使用不同的转换器,并且我将该接口用作父对象中的属性类型,则会出现问题 在下面的代码示例中,请注意ConverterClassA在第二个测试用例中使用,但在第一个测试用例中没有使用 是否有人对此有解决方法,以便根据反序列

我正在使用Json.NET并将TypeNameHandling设置为Object或All。当反序列化程序为对象选择转换器时,我发现它将声明的对象类型传递给每个JsonConverter的CanConvert,而不是实际类型(如对象的$type节点所述)

如果我为实现公共接口的不同类使用不同的转换器,并且我将该接口用作父对象中的属性类型,则会出现问题

在下面的代码示例中,请注意ConverterClassA在第二个测试用例中使用,但在第一个测试用例中没有使用

是否有人对此有解决方法,以便根据反序列化对象的实际类型而不是序列化对象的声明类型来选择转换器

(注意,虽然这个代码示例没有显示它,但是序列化(编写JSON)确实正确地使用了成员的实际类型,而不是声明的类型。它似乎只是反序列化器(读取JSON),我将其定义为“断开”)

先谢谢你,-埃里克

interface IMyInterface
{
}

class ClassA : IMyInterface
{
}

class ParentOfInterface
{
    public IMyInterface Child;
}

class ParentOfA
{
    public ClassA Child;
}

class ConverterClassA : JsonConverter
{
    public override bool CanWrite { get { return false; } } // only read
    public override bool CanConvert(Type objectType)
    {
        Debug.WriteLine(String.Format("{0}.CanConvert({1})", this.GetType().Name, objectType.Name));
        return objectType == typeof(ClassA);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        Debug.WriteLine(String.Format("{0}.ReadJson() CONVERTER IS BEING USED!", this.GetType().Name));
        var ret = new ClassA();
        serializer.Converters.Remove(this);
        serializer.Populate(reader, ret);
        serializer.Converters.Add(this);
        return ret;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var settings = new JsonSerializerSettings
        {
            Formatting = Formatting.Indented,
            TypeNameHandling = TypeNameHandling.All,
            Converters = new JsonConverter[] { new ConverterClassA() }
        };

        Debug.WriteLine("Testing ParentOfInterface");
        var pi = new ParentOfInterface();
        pi.Child = new ClassA();
        var str = JsonConvert.SerializeObject(pi, settings);
        Debug.WriteLine("Going to Deserialize ParentOfInterface");
        var pi2 = JsonConvert.DeserializeObject<ParentOfInterface>(str, settings); // converter IS NOT used!

        Debug.WriteLine("Testing ParentOfA");
        var pa = new ParentOfA();
        pa.Child = new ClassA();
        var stra = JsonConvert.SerializeObject(pa, settings);
        Debug.WriteLine("Going to Deserialize ParentOfA");
        var pa2 = JsonConvert.DeserializeObject<ParentOfA>(stra, settings); // converter IS used!
    }
}
这是事实——一旦您使用了
JsonConverter
,它将完全控制反序列化,包括解析
“$type”
。有关在
ReadJson()中实现处理
“$type”
的方法,请参见或。这是事实——一旦使用
JsonConverter
,它将完全控制反序列化,包括解析
“$type”
。有关在
ReadJson()中实现处理
“$type”
的方法,请参阅或。
Testing ParentOfInterface
ConverterClassA.CanConvert(ParentOfInterface)
ConverterClassA.CanConvert(ClassA)
Going to Deserialize ParentOfInterface
ConverterClassA.CanConvert(ParentOfInterface)
ConverterClassA.CanConvert(IMyInterface) **note, converter is not used! ***
Testing ParentOfA
ConverterClassA.CanConvert(ParentOfA)
ConverterClassA.CanConvert(ClassA)
Going to Deserialize ParentOfA
ConverterClassA.CanConvert(ParentOfA)
ConverterClassA.CanConvert(ClassA)
ConverterClassA.ReadJson() CONVERTER IS BEING USED!