首页 > 解决方案 > 当 c# 对象不是 JSON 可序列化时

问题描述

在阅读一些关于克隆对象的文献时,我遇到了这个短语

“如果您的对象是开箱即用的 JSON 可序列化对象”

有人可以解释一下吗?

最好有一些相反的例子(一个不是开箱即用JSON可序列化的对象的情况)

标签: c#jsonserialization

解决方案


尝试使用 Newtonsoft.Json 序列化具有 TcpClient 属性的对象:

using Newtonsoft.Json;
using System.Net.Sockets;

class A
{ 
    public TcpClient TcpClient { get; set; } = new TcpClient();
}

var a = new A();

JsonConvert.SerializeObject(a);

它将抛出以下异常:

Error getting value from 'MulticastLoopback' on 'System.Net.Sockets.Socket'.

从 TcpClient 访问 MulticastLoopback 会抛出异常:

var ml = a.TcpClient.Client.MulticastLoopback;

但如果我们有 UdpClient 代替:

class A
{ 
    public UdpClient UdpClient { get; set; } = new UdpClient();
}

var a = new A();
var ml = a.UdpClient.Client.MulticastLoopback; // ok here

JsonConvert.SerializeObject(a); // Exception here

然后访问该特定属性不会失败,但会失败

var ls = a.UdpClient.Client.LingerState;

并且序列化会抛出异常:

Error getting value from 'LingerState' on 'System.Net.Sockets.Socket'.

UdpClient 和 TcpClient 共享公共属性“.Client”,该属性属于一个类型System.Net.Sockets.Socket,该类中的一些成员仅对 TCP 连接有效,而一些仅对 UDP 连接有效。

MulticastLoopback 不能从 TCP 套接字访问,LingerState 不能从 UDP 套接字访问,因此 TcpClient 和 UdpClient 不是“开箱即用的 JSON 可序列化”。

编辑:总而言之,某些类型的对象的序列化没有意义,因此它们不是设计为可序列化的。套接字类就是其中之一。


推荐阅读