2013-10-03 4 views
5

protobuf-net v2ビルド668を使用して、次のように定義されたメンバを含むクラスを直列化/逆シリアル化しようとしています。同時にオンザフライ変換を実行することができます。 通常、サロゲートアプローチはうまくいくはずですが、C#ではユーザー定義のインターフェイス変換が許可されていないため、コンバージョンを定義することはできません。protobuf-netサロゲートクラスの代替変換関数を定義する方法はありますか?

おかげで、現在のビルドで

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

ちょうど:私はあなたを無視していない - 家の移動のために、私は今日のPCの時間が限られている。あなたにできるだけ早く戻ります –

+0

ありがとうMarc。移動に幸運。 –

答えて

3

:いいえ、ありません。

ただし、次のビルドでは、これが正常に動作します:

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

基本的には、static方法は[ProtoConverter]をマークは[ProtoConverter]方法があるというさらなる利点で、定義されimplicitまたはexplicit変換演算子に優先します演算子と同じ統語規則の影響を受けません。インテントが署名から明らかであるので、個別の*To/*From属性を定義する必要はありません。

注:Dummyの属性は不要であり、使用されることはありません。

+0

それは完璧です。次のビルドを楽しみにしています。どうもありがとう。 Franck –

+0

混乱を避けるため、ダミーの属性を削除しました。 –

+0

Marc、このビルドはNuGetには一度もリリースされていないようですが、それについての計画はありますか?または、ソースからprotobuf-netをビルドする必要がありますか? –

関連する問題