当 serialize/deserialize 一个可枚举实例时,protobuf-net 使用什么迭代方法?
What iterate method does protobuf-net used when serialize/deserialize an enumerable instance?
可枚举实例可能来自 List、Dictionary、ConcurrentDictionary 或我自己的 class。
如果你有一个 class 和一个普通的 IEnumerable
属性,像这样:
[ProtoContract]
class Dummy
{
[ProtoMember(1)]
public IEnumerable<string> Values { get; set; }
}
然后,当 protobuf-net 反序列化对象时,实际的底层对象将是一个 List<T>
- 在这种情况下,一个 List<string>
.
对于序列化,如果您将其设置为一些完全自定义的可枚举实现,protobuf-net 将按正常方式简单地迭代它并序列化每个值。
这是一个非常复杂的问题。当 序列化 时,它 大多数 只使用 foreach
,即 GetEnumerator()
API - 或平面索引器 -基于数组的枚举。当反序列化时,它主要试图寻找.Add(YourType t)
方法。对于字典,它将查找 Add(KeyValuePair<TKey, TValue>)
、Add(TKey, TValue)
或索引器 TValue this[TKey]
(特别是 "maps")中的任何一个。
但是!现实比这更微妙,因为我们还需要考虑一系列更复杂的集合类型。对于 2.4.*,这 非常 很难理解,因为它都是运行时 IL,但是:对于 3.0 分支,您可以看到一些场景 here - 特别是,见:
- RepeatedSerializer.cs
- RepeatedSerializer.Immutable.cs
- RepeatedSerializer.Concurrent.cs
- MapSerializer.cs
- MapSerializer.Immutable.cs
- MapSerializer.Concurrent.cs
通常,然而:答案是:"it'll just work".
可枚举实例可能来自 List、Dictionary、ConcurrentDictionary 或我自己的 class。
如果你有一个 class 和一个普通的 IEnumerable
属性,像这样:
[ProtoContract]
class Dummy
{
[ProtoMember(1)]
public IEnumerable<string> Values { get; set; }
}
然后,当 protobuf-net 反序列化对象时,实际的底层对象将是一个 List<T>
- 在这种情况下,一个 List<string>
.
对于序列化,如果您将其设置为一些完全自定义的可枚举实现,protobuf-net 将按正常方式简单地迭代它并序列化每个值。
这是一个非常复杂的问题。当 序列化 时,它 大多数 只使用 foreach
,即 GetEnumerator()
API - 或平面索引器 -基于数组的枚举。当反序列化时,它主要试图寻找.Add(YourType t)
方法。对于字典,它将查找 Add(KeyValuePair<TKey, TValue>)
、Add(TKey, TValue)
或索引器 TValue this[TKey]
(特别是 "maps")中的任何一个。
但是!现实比这更微妙,因为我们还需要考虑一系列更复杂的集合类型。对于 2.4.*,这 非常 很难理解,因为它都是运行时 IL,但是:对于 3.0 分支,您可以看到一些场景 here - 特别是,见:
- RepeatedSerializer.cs
- RepeatedSerializer.Immutable.cs
- RepeatedSerializer.Concurrent.cs
- MapSerializer.cs
- MapSerializer.Immutable.cs
- MapSerializer.Concurrent.cs
通常,然而:答案是:"it'll just work".