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方法来填充集合。