首页 > 解决方案 > c# Json.net 不可变类

问题描述

我看到了其他类似的问题/答案,但没有一个同时显示序列化/反序列化

例子:

public class DeepNested {
    [JsonProperty]
    int X { get; }

    [JsonProperty]
    int Y { get; }

    public DeepNested(int x, int y) { X = x; Y = y; }

    [JsonConstructor]
    public DeepNested(DeepNested dn) { X = dn.X; Y = dn.Y; }
}

public class Nested {
    [JsonProperty]
    DeepNested DN { get; }

    [JsonProperty]
    int Z { get; }

    [JsonProperty]
    int K { get; }

    [JsonConstructor]
    public Nested(DeepNested dn, int z, int k) { DN = new DeepNested(dn); Z = z; K = k; }
}

public class C {
    [JsonProperty]
    Nested N { get; }

    [JsonConstructor]
    public C(Nested n) { N = n; }
}

class Program {
    static void Main(string[] args) {
        var deepNested = new DeepNested(1,2);
        var nested = new Nested(deepNested, 3, 4);
        C c = new C(nested);
        string json = JsonConvert.SerializeObject(c);
        C c2 = JsonConvert.DeserializeObject<C>(json);
        Console.WriteLine(json);
    }
}

我得到一个例外DeepNested.DeepNested(DeepNested dn)

System.NullReferenceException: 'Object reference not set to an instance of an object.'

调试器显示 dn 是null

这似乎是 Json.NET 的一个严重限制,除非我遗漏了什么?

标签: c#json.net

解决方案


@IpsitGaur 是对的,通常您应该有一个默认的公共构造函数和可公开访问的属性(可变)。但是 JSON.Net 是一个非常强大的工具!

如果需要处理非默认构造函数,可以使用JsonConstructorAttribute。对于您的代码,示例可能如下所示:

public class Nested
{
    public int X { get; }
    public int Y { get; }

    [JsonConstructor]
    Nested(int x, int y) { X=x; Y=y; }
}

public class C
{
    public Nested N { get; }

    [JsonConstructor]
    public C(Nested n) { N = n; }
}

var c1 = new C(new Nested(1, 2));
var json = JsonConvert.SerializeObject(c1); // produce something like "{\"n\":{\"x\":1,\"y\":2}}";
var c2 = JsonConvert.DeserializeObject<C>(json);

推荐阅读