问题描述
我有一个实现 IEnumerable 的集合类,但在反序列化它的序列化版本时遇到了麻烦.我正在使用 Json.net v 4.0.2.13623
这是我的集合类的一个更简单的版本,它说明了我的问题
公共类 MyType{public int Number { 得到;私人订制;}公共 MyType(整数){this.Number = 数字;}}公共类 MyTypes : IEnumerable{private readonly Dictionaryc_index;公共 MyTypes(IEnumerable 种子){this.c_index = seed.ToDictionary(item => item.Number);}公共 IEnumerator获取枚举器(){返回 this.c_index.Values.GetEnumerator();}IEnumerator IEnumerable.GetEnumerator(){返回 this.GetEnumerator();}公共 int CustomMethod(){返回 1;//只是为了说明}}
当我序列化它时,我得到以下 json
[{1号},{2号}]但是当我尝试反序列化时,出现以下异常System.Exception:无法创建和填充列表类型 MyTypes
也曾尝试使用序列化提示但没有成功
这些是我用过的测试函数
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<MyTypes>(_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<MyType>
有一个构造函数,它接受一个 IEnumerable
输入参数.来自 发行说明:
致所有未来不可变 .NET 集合的创建者:如果您的 T 集合有一个接受 IEnumerable 的构造函数,那么在反序列化到您的集合时,Json.NET 将自动工作,否则您就走运了.
由于问题中的 MyTypes
类具有这样的构造函数,所以现在 可以正常工作.演示小提琴:https://dotnetfiddle.net/LRJHbd.
如果没有这样的构造函数,就需要添加一个无参数的构造函数并用一个有效的实现
方法.然后 Json.NET 可以构造和填充集合.或者反序列化为中间集合,如原始答案.ICollection
(而不仅仅是IEnumerable
)>Add(MyType item)
I have a collection class that implements IEnumerable and I am having trouble deserializing a serialized version of the same. I am using Json.net v 4.0.2.13623
Here is a simplier version of my collection class that illustrates my issue
public class MyType
{
public int Number { get; private set; }
public MyType(int number)
{
this.Number = number;
}
}
public class MyTypes : IEnumerable<MyType>
{
private readonly Dictionary<int, MyType> c_index;
public MyTypes(IEnumerable<MyType> seed)
{
this.c_index = seed.ToDictionary(item => item.Number);
}
public IEnumerator<MyType> GetEnumerator()
{
return this.c_index.Values.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public int CustomMethod()
{
return 1; // Just for illustration
}
}
When I serialize it i get the following json
[
{
"Number": 1
},
{
"Number": 2
}
]
But then when i try to deserialize i get the following exceptionSystem.Exception: Cannot create and populate list type MyTypes
Have also tried using serialization hints but have had no success
These are the test function i have used
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<MyTypes>(_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<MyTypes>(_jsonContent, _serializationSettings);
}
Has anybody managed to serialize their own collection objects ?
Thanks in advance
Pat
As of Json.NET 6.0 Release 3 and later (I tested on 8.0.3), this works automatically as long as the custom class implementing IEnumerable<MyType>
has a constructor that takes an IEnumerable<MyType>
input argument. From the release notes:
Since the MyTypes
class in the question has just such a constructor, this now just works. Demonstration fiddle: https://dotnetfiddle.net/LRJHbd.
Absent such a constructor, one would need to add a parameterless constructor and implement ICollection<MyType>
(instead of just IEnumerable<MyType>
) with a working Add(MyType item)
method. Json.NET can then construct and populate the collection. Or deserialize to an intermediate collection as in the original answer.
这篇关于实现 IEnumerable<T> 的自定义集合的 Json.net 序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!