2017-07-20 4 views
0

Est-ce que protobuf-net prend en charge la sérialisation de named tuples?Est-ce que protobuf-net prend en charge les tuples?

par exemple

[ProtoMember(1)] 
protected readonly SortedDictionary<double, (double Bid, double Ask, double Open, double High, double Low, double Close, int Volume, int OpenInt)> FuturesCurveData; 
+0

Pour ceux qui votent en bas, notez pas différente de cette question https://stackoverflow.com/questions/4763875/does-protobuf-net-support-nullable-types – screig

+0

Cette question a le code @screig. Pouvez-vous ajouter du code à votre question? – mjwills

+0

@mjwills là vous allez – screig

Répondre

3

"En partie oui, en partie non".

protobuf-net n'a pas connaissance spécifique de tuples nommés et the names are not available to library code, mais à partir de v2.2.0 partir, protobuf-net est en mesure de déduire un contrat pour ValueTuple<...> types, essentiellement le traiter comme un type de position - donc Bid serait champ 1, Ask serait champ 2, etc Certains code comme GetProto<T> va pas produire les résultats que vous attendez (depuis a: il ne peut pas voir les noms, et b: la forme devient très étrange pour les grands tuples), et vous ne serez pas en mesure de contrôler les détails de sérialisation à grain fin (DataFormat, etc), mais: cela devrait fonctionner.

Les belles œuvres suivantes:

using ProtoBuf; 
using System.Collections.Generic; 

static class P 
{ 
    static void Main() 
    { 
     var obj = new MyType { FuturesCurveData = { 
       { 1.0, (1, 2, 3, 4, 5, 6, 7, 8) }, 
       { 2.0, (2, 3, 4, 5, 6, 7, 8, 9) }, 
      } }; 
     var clone = Serializer.DeepClone(obj); 
     foreach(var pair in clone.FuturesCurveData) 
     { 
      System.Console.WriteLine($"{pair.Key}: {pair.Value}"); 
     } 
    } 
} 
[ProtoContract] 
class MyType 
{ 
    [ProtoMember(1)] 
    public SortedDictionary<double, (double Bid, double Ask, double Open, double High, double Low, double Close, int Volume, int OpenInt)> FuturesCurveData { get; } = 
    new SortedDictionary<double, (double Bid, double Ask, double Open, double High, double Low, double Close, int Volume, int OpenInt)>(); 
} 

sortie:

1: (1, 2, 3, 4, 5, 6, 7, 8) 
2: (2, 3, 4, 5, 6, 7, 8, 9) 

Et voici ce que GetProto<MyType>() produit - pas tout à fait un tel succès:

syntax = "proto2"; 
package System; 

message KeyValuePair_Double_ValueTuple_Double_Double_Double_Double_Double_Double_Int32_ValueTuple_Int32 { 
    optional double Key = 1; 
    optional ValueTuple_Double_Double_Double_Double_Double_Double_Int32_ValueTuple_Int32 Value = 2; 
} 
message MyType { 
    repeated KeyValuePair_Double_ValueTuple_Double_Double_Double_Double_Double_Double_Int32_ValueTuple_Int32 FuturesCurveData = 1; 
} 
message ValueTuple_Double_Double_Double_Double_Double_Double_Int32_ValueTuple_Int32 { 
    optional double Item1 = 1; 
    optional double Item2 = 2; 
    optional double Item3 = 3; 
    optional double Item4 = 4; 
    optional double Item5 = 5; 
    optional double Item6 = 6; 
    optional int32 Item7 = 7; 
    optional ValueTuple_Int32 Rest = 8; 
} 
message ValueTuple_Int32 { 
    optional int32 Item1 = 1; 
} 

Comme une note de côté, il devrait travailler comme map<,> si le type de clé était int ou string, mais qu'il semble avoir atteint un bogue, lequel I have logged.

+0

merci Marc! En ce qui concerne la documentation, je ne m'attendrais pas à ce qu'elle couvre tous les scénarios. D'où la question, merci encore pour votre réponse détaillée et utile. Sean – screig