protobuf-net試圖避免編碼到任何特定集合類型,而是試圖檢測一些密鑰模式;特別是看起來像IList
,ICollection<T>
,甚至只是一個自定義迭代器和Add(Foo)
,其中GetEnumerator()
返回一個迭代器,其中.Current
類型Foo
。
SortedDictionary<TKey,TValue>
implements ICollection<KeyValuePair<TKey, TValue>>
,這是protobuf-net檢測和使用的東西;因此該庫將其簡單地視爲鍵值對的集合,調用.Add
等。KeyValuePair<TKey,TValue>
被模式邏輯再次視爲「自動元組」:它具有構造函數,它接受所有公共成員,因此它將它們映射(構造函數爲KeyValuePair(TKey key, TValue value)
,所以.Key
被映射爲字段1,而.Value
被映射爲字段2)。通過架構
[ProtoContract]
class Foo
{
private readonly SortedDictionary<string, int> items =
new SortedDictionary<string, int>(
StringComparer.InvariantCultureIgnoreCase);
[ProtoMember(1)]
SortedDictionary<string, int> Items { get { return items; } }
}
(可驗證通過Serializer.GetProto<Foo>()
):把這個在一起,protobuf網地圖
message Foo {
repeated KeyValuePair_String_Int32 Items = 1;
}
message KeyValuePair_String_Int32 {
optional string Key = 1;
optional int32 Value = 2;
}
因此,基本上,它應該很好地工作;唯一需要注意的是確保自定義IComparer<CustomTKey>
得到應用。我通過只給protobuf-net訪問getter,並在我們的自定義類型中執行收集啓動 - 但如果您想啓用構造函數,也可以使用反序列化前回調來執行相同的操作-skipping。
做了「before-deserialization callback」屬於無參數構造函數嗎? – mcmillab
@mcmillab通常不會;回調方法是已知簽名的方法,通常通過接口或屬性進行註釋;在protobuf-net的情況下,它是一個屬性; '[ProtoBeforeDeserialization]'。 –