6

protobuf-net v2 ビルド 668 を使用して、オンザフライ変換を同時に実行しながら、インターフェイスとして定義されたメンバーを含むクラスをシリアル化/逆シリアル化しようとしています。通常、代理アプローチは問題なく機能しますが、C# ではインターフェイスのユーザー定義の変換が許可されていないため、変換を定義することはできません。

ありがとう、

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

1 に答える 1

4

現在のビルド: いいえ、ありません。

ただし、次のビルドでは、これは正常に機能します。

[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マークされたメソッドは、定義されたor変換演算子[ProtoConverter]よりも優先されます。さらに、メソッドは演算子と同じ構文規則に従わないという利点があります。署名から意図が明らかであるため、個別の/属性を定義する必要はありません。implicitexplicit[ProtoConverter]*To*From

補足として: on の属性Dummyは不要であり、使用されることはありません。

于 2013-10-07T09:05:37.253 に答える