Json.net实现IEnumerable 的自定义集合的序列化

我有一个实现IEnumerable的集合类,我无法反序列化相同的序列化版本。 我正在使用Json.net v 4.0.2.13623

这是我的集合类的简化版本,它说明了我的问题

public class MyType { public int Number { get; private set; } public MyType(int number) { this.Number = number; } } public class MyTypes : IEnumerable { private readonly Dictionary c_index; public MyTypes(IEnumerable seed) { this.c_index = seed.ToDictionary(item => item.Number); } public IEnumerator GetEnumerator() { return this.c_index.Values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); } public int CustomMethod() { return 1; // Just for illustration } } 

当我序列化它时,我得到以下json

 [ { "Number": 1 }, { "Number": 2 } ] 

但是当我尝试反序列化时,我得到以下exceptionSystem.Exception:无法创建和填充列表类型MyTypes

还试过使用序列化提示但没有成功

这些是我用过的测试function

 public void RoundTrip() { var _myTypes1 = new MyTypes(new[] { new MyType(1), new MyType(2) }); var _jsonContent = JsonConvert.SerializeObject(_myTypes1, Formatting.Indented); var _myTypes2 = JsonConvert.DeserializeObject(_jsonContent); } public void RoundTripWithSettings() { var _myTypes1 = new MyTypes(new[] { new MyType(1), new MyType(2) }); var _serializationSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Arrays }; var _jsonContent = JsonConvert.SerializeObject(_myTypes1, Formatting.Indented, _serializationSettings); var _myTypes2 = JsonConvert.DeserializeObject(_jsonContent, _serializationSettings); } 

有人设法序列化自己的集合对象吗?

提前致谢

从Json.NET 6.0 Release 3及更高版本开始(我在8.0.3上测试过),只要实现IEnumerable的自定义类具有一个带有IEnumerable输入参数的构造函数,它就会自动IEnumerable 。 从发行说明 :

对于所有未来的不可变.NET集合的创建者:如果你的T集合有一个带有IEnumerable的构造函数,那么Json.NET会在反序列化到你的集合时自动工作,否则你都会运气不好。

由于问题中的MyTypes类只有这样的构造函数,所以现在只能工作 。 示范小提琴: https : //dotnetfiddle.net/LRJHbd 。

如果没有这样的构造函数,则需要添加无参数构造函数并使用有效的Add(MyType item)方法实现ICollection (而不仅仅是IEnumerable )。 然后Json.NET可以构建和填充集合。 或者像原始答案一样反序列化为中间集合。

我相信JSON .NET依赖于为其反序列化的类型提供无参数构造函数。 从反序列化的角度来看,它不知道向建设者提供什么。

至于你的集合,又如何知道如何填充IEnumerable ,它只定义如何枚举集合而不是如何填充它。 您应该直接反序列化为某些标准IEnumerable (或直接反向IEnumerable ,我相信JSON.NET支持),然后将其传递给您的构造函数。

我相信以下所有情况都适用于这种情况:

 var _myTypes2 = new MyTypes(JsonConvert.DeserializeObject(_jsonContent)); var _myTypes2 = new MyTypes(JsonConvert.DeserializeObject>(_jsonContent)); var _myTypes2 = new MyTypes(JsonConvert.DeserializeObject>(_jsonContent)); 

或者,虽然需要更多工作,但如果需要直接反序列化,则可以在集合中实现类似IList的内容,这应该允许JSON.NET使用IList方法来填充集合。