2013-10-03 14 views
5

Usando protobuf-net v2 build 668, sto provando a serializzare/deserializzare una classe che contiene un membro definito come interfaccia mentre si effettuano conversioni al volo contemporaneamente. Normalmente, l'approccio surrogato funzionerebbe bene ma poiché C# non consente conversioni definite dall'utente per le interfacce, non posso definire le conversioni.C'è un modo per definire le funzioni di conversione alternative (da/verso le interfacce) in una classe surrogata protobuf-net

Grazie,

namespace ProtoBufNetTest 
{ 
    using System.Diagnostics; 
    using System.IO; 

    using ProtoBuf; 
    using ProtoBuf.Meta; 

    class Program 
    { 
     static void Main() 
     { 
      RuntimeTypeModel.Default.Add(typeof(IDummy), false) 
       .SetSurrogate(typeof(DummySurrogate)); 

      var container = new Container { Data = new Dummy { Positive = 3 } }; 

      using (var file = File.Create("test.bin")) 
      { 
       Serializer.Serialize(file, container); 
      } 

      using (var file = File.OpenRead("test.bin")) 
      { 
       container = Serializer.Deserialize<Container>(file); 
       Debug.Assert(container.Data.Positive == 3); 
      } 
     } 
    } 

    // Outside of the project, cannot be changed 
    public interface IDummy 
    { 
     int Positive { get; set; } 
    } 

    [ProtoContract] 
    public class Container 
    { 
     [ProtoMember(1)] 
     public IDummy Data { get; set; } 
    } 

    public class Dummy : IDummy 
    { 
     public int Positive { get; set; } 
    } 

    [ProtoContract] 
    class DummySurrogate 
    { 
     [ProtoMember(1)] 
     public int Negative { get; set; } 

     // Does not compile : user-defined conversions to or from an interface are not allowed 
     public static explicit operator IDummy(DummySurrogate value) 
     { 
      return value == null ? null : new Dummy { Positive = -value.Negative }; 
     } 

     // Does not compile : user-defined conversions to or from an interface are not allowed 
     public static explicit operator DummySurrogate(IDummy value) 
     { 
      return value == null ? null : new DummySurrogate { Negative = -value.Positive }; 
     } 

     // Fake attribute, does not exist but could work if it did 
     [ProtoConvertFrom] 
     public static IDummy From(DummySurrogate value) 
     { 
      return value == null ? null : new Dummy { Positive = -value.Negative }; 
     } 

     // Fake attribute, does not exist but could work if it did 
     [ProtoConvertTo] 
     public static DummySurrogate To(IDummy value) 
     { 
      return value == null ? null : new DummySurrogate { Negative = -value.Positive }; 
     } 
    } 
} 
+0

Solo per dire: non ti sto ignorando - a causa di una mossa di casa ho un tempo limitato per il PC oggi. Torneremo da voi al più presto –

+0

Grazie Marc. Buona fortuna con la mossa. –

risposta

3

Nella build attuale: no, non c'è.

Tuttavia, nella prossima generazione, questo funziona bene:

[ProtoContract] 
class DummySurrogate 
{ 
    [ProtoMember(1)] 
    public int Negative { get; set; } 

    [ProtoConverter] 
    public static IDummy From(DummySurrogate value) 
    { 
     return value == null ? null : new Dummy { Positive = -value.Negative }; 
    } 

    [ProtoConverter] 
    public static DummySurrogate To(IDummy value) 
    { 
     return value == null ? null : new DummySurrogate 
      { Negative = -value.Positive }; 
    } 
} 

Fondamentalmente, un metodo static contrassegnati [ProtoConverter] ha priorità su un operatore implicit o explicit conversione definito, con l'ulteriore vantaggio che [ProtoConverter] metodi sono non soggetto alle stesse regole sintattiche degli operatori. Non è necessario definire attributi separati *To/*From, poiché l'intento è chiaro dalla firma.

Come nota a margine: gli attributi su Dummy non sono necessari e non vengono mai utilizzati.

+0

Questo è perfetto. In attesa della prossima build. Molte grazie. Franck –

+0

Ho rimosso gli attributi su Dummy per evitare qualsiasi confusione. –

+0

Marc, sembra che questa build non sia mai stata rilasciata a NuGet, ci sono dei piani per farlo o dovrei creare protobuf-net dalla sorgente? –