Json.NET - 值类型成员未被反序列化?

9

我一直在试用Json.NET,并且非常喜欢它。然而,在反序列化具有值类型成员的对象时遇到了问题。例如,考虑以下代码:

public struct Vector
{
    public float X;
    public float Y;
    public float Z;

    public override string ToString()
    {
        return string.Format("({0},{1},{2})", X, Y, Z);
    }
}

public class Object
{
    public Vector Position;
}

class Program
{
    static void Main(string[] args)
    {
        var obj = new Object();
        obj.Position = new Vector { X = 1, Y = 2, Z = 3 };

        var str = JsonConvert.SerializeObject(obj);

        Console.WriteLine(str); // {"Position":{"X":1.0,"Y":2.0,"Z":3.0}}

        obj = JsonConvert.DeserializeObject<Object>(str);

        Console.WriteLine(obj.Position); // (0,0,0)

        Console.ReadKey(true);
    }
}

该位置已正确序列化,但在反序列化过程中未能恢复。有趣的是,以下代码按预期工作。

class Program
{
    static void Main(string[] args)
    {
        var vec = new Vector { X = 1, Y = 2, Z = 3 };

        var str = JsonConvert.SerializeObject(vec);

        Console.WriteLine(str); // {"X":1.0,"Y":2.0,"Z":3.0}

        vec = JsonConvert.DeserializeObject<Vector>(str);

        Console.WriteLine(vec); // (1,2,3)

        Console.ReadKey(true);
    }
}

正如您所看到的,向量本身已经被正确地序列化/反序列化。对于第一个场景,是否有简单的解决方案,还是我需要创建类似于自定义转换器的东西?


2
定义一个名为 Object 的类会引起麻烦。 - JaredPar
1
我同意,但我可以肯定地说这不是问题的根源。 - kloffy
1个回答

9

您有两个选项。

  1. Change the Vector struct to a class
  2. Or Change:

    obj = JsonConvert.DeserializeObject<Object>(str);
    

    to

    obj = JsonConvert.DeserializeObject<Object>(str, new JsonSerializerSettings{ ObjectCreationHandling = ObjectCreationHandling.Replace});
    

向量结构体是由一个库提供的,因此第一个建议不可行,但第二个建议有效。我想知道让Json.NET意识到值类型并执行默认情况下对它们执行的ObjectCreationHandling.Replace需要多少工作量。(另外,PreserveReferencesHandling.All对于值类型也没有太多意义,因此不需要为它们提供"$id"。) - kloffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接