2013-10-03 22 views
5

'daki alternatif dönüştürme işlevlerini tanımlamanın bir yolu var mı? Protobuf-net v2 build 668'i kullanarak, tanımlanmış bir üyesi içeren bir sınıfı seri hale getirmeye/serpiştirmeye çalışıyorum Aynı anda anında dönüşümleri yaparken arayüz. Normal olarak, vekil yaklaşımı iyi çalışır, ancak C#, arayüzler için kullanıcı tanımlı dönüşümlere izin vermediğinden, dönüşümleri tanımlayamıyorum.Bir protobuf-net vekil sınıfı

sayesinde cari yapı olarak

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

Sadece şunu söyleyeyim: Seni görmezden gelmiyorum - bir eve taşındığı için bugün PC zamanı sınırlı. Size geri dönecek –

+0

Teşekkürler Marc. Hareketle iyi şanslar. –

cevap

3

: hayır, yok. Temel olarak,

[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 }; 
    } 
} 

bir static yöntem [ProtoConverter][ProtoConverter] yöntemler bir başka avantaj ile, tanımlanmış bir implicit veya explicit dönüşüm operatör önceliklidir işaretlenmiş:

Bununla birlikte, bir sonraki yapı içinde bu iyi çalışır operatörler ile aynı sözdizim kurallarına tabi değildir. Amacı, imzadan net olduğu için ayrı *To/*From öznitelikleri tanımlamak gerekli değildir.

Bir yan not olarak: Dummy'daki özellikler gereksizdir ve hiçbir zaman kullanılmaz.

+0

Bu mükemmel. Bir sonraki inşa için bekliyorum. Çok teşekkürler. Franck –

+0

Herhangi bir karışıklığı önlemek için Dummy'deki özellikleri kaldırdım. –

+0

Marc, bu yapının hiç bir zaman NuGet'e bırakılmamış gibi görünüyor, bunun için bir plan var mı, yoksa protobuf-net'i kaynaktan mı oluşturmalıyım? –