6

最近、proto3 を使用するようにコード ベース (Java、C++、および C#) をアップグレードしました。C# の場合、これにはコードへの 2000 以上の変更が含まれます。これはほとんどセマンティックであり、すべて問題ありませんが、理解できない問題が 1 つあります。シリアライゼーション/デシリアライゼーション。タイプをデシリアライズするための次の修正されたメソッドがありIMessageます (proto2 でこれを行うコードはコメントされています)。これは、GitHub リポジトリ内の例に示されているコードです...

public static T ToObject<T>(this byte[] buf) where T : IMessage 
{
    if (buf == null)
        return default(T);

    using (MemoryStream ms = new MemoryStream())
    {
        ms.Write(buf, 0, buf.Length);
        ms.Seek(0, SeekOrigin.Begin);

        MessageParser parser = new MessageParser();
        return (T)parser.ParseFrom(ms);
            //ProtoBuf.Serializer.Deserialize<T>(ms);
    }
}

しかし、行MessageParser parser = new MessageParser();は私にデザイン/コンパイル時のエラーを与えています

MessageParser には、引数が 0 のコンストラクターが含まれていません

逆にproto3ドキュメントについて知っているので、それは興味深いことです。

私が知りたいのは、proto3 を使用して、デシリアライゼーションを実行する方法です。

御時間ありがとうございます。


注、私のシリアル化コードは

public static byte[] ToByteArray<T>(this T o) where T : IMessage 
{
    if (o == null)
        return null;

    using (MemoryStream ms = new MemoryStream())
    {
        o.WriteTo(ms);
        return ms.ToArray();
    }
}

これはコンパイルされますが、正しいですか?

4

1 に答える 1

8

デシリアライゼーションのコンパイル時エラーについては、ドキュメントでは、関数ファクトリとしてを渡して のFunc<T>インスタンスを作成Tし、 のコンストラクターにMessageParser<T>渡す必要があると説明されています。

() => new T()メッセージを作成するために必要なものに応じて、より複雑な機能になる可能性があります。

完全なコード:

public static T ToObject<T>(this byte[] buf) where T : IMessage<T>, new()
{
    if (buf == null)
        return default(T);

    using (MemoryStream ms = new MemoryStream())
    {
        ms.Write(buf, 0, buf.Length);
        ms.Seek(0, SeekOrigin.Begin);

        MessageParser<T> parser = new MessageParser<T>(() => new T());
        return parser.ParseFrom(ms);
    }
}

ドキュメントによると、シリアル化は問題ないはずです。

于 2016-02-11T12:11:40.330 に答える