3

私は一連のプロトコル バッファ (protobuf-net を使用) を持つシステムを作成しています。すべて継承する抽象クラスで次のようなものを定義したいと考えています。

public byte[] GetBytes()

ただし、プロトコル バッファ シリアル化には型引数が必要です。継承クラスの型を取得する効率的な方法はありますか?

例:

public byte[] GetBytes()
    {
        using (MemoryStream stream = new MemoryStream())
        {
            Serializer.Serialize<T /* what goes here? */>(stream, this);
            return stream.ToArray();
        }
    }
4

4 に答える 4

4

「T」と書くだけですよね?

そして、あなたのクラス宣言で:

public class M<T>

?

- 編集

そして、それを継承すると:

public class Foo : M<Apple>
于 2009-08-17T00:08:27.903 に答える
3

基本クラスを として定義しBaseClass<T>、派生クラスで T をシリアライザーの type に置き換えますDerivedClass<SerializerType>

型引数に制約を指定することもできます。

BaseClass<T> where T : SerializerBase

ここでは、適用できる制約の種類について説明します。

于 2009-08-17T00:10:56.230 に答える
3

これはリフレクションを介して行うことができますが、protobuf-net が自動的に行います。

呼び出しを次のように変更するだけです。

Serializer.NonGeneric.Serialize(stream, this /* Takes an object here */);

これは、リフレクションを介して実行時にジェネリック メソッドを構築することで機能します。詳細については、コードを確認してください ( 2 番目の方法はこちら)。

于 2009-08-17T00:13:44.050 に答える
1

ここでは実際には特別なことは何も必要ありません...protobuf-netは継承を尊重するためです。あなたが持っている場合:

[ProtoInclude(typeof(Foo), 20)]
[ProtoInclude(typeof(Bar), 21)]
public abstract class MyBase {
    /* other members */

    public byte[] GetBytes()
    {
        using(MemoryStream ms = new MemoryStream())
        {
            Serializer.Serialize<MyBase>(ms, this); // MyBase can be implicit
            return ms.ToArray();
        }
    }
}
[ProtoContract]
class Foo : MyBase { /* snip */ }
[ProtoContract]
class Bar : MyBase { /* snip */ }

その後、それは動作します。データをシリアル化するために、データは常に基本(契約)タイプから始まります。したがってSerializer.Serialize<Foo>(stream, obj)、最初に行ったとしても、コントラクトである基本クラスがあることを検出し、に切り替えMyBaseます。デシリアライズ中に、正しい派生(具象)タイプを識別してそれを使用するので、で使用することもできDeserialize、元のデータが何であったかに応じてまたはMyBaseを構築します。FooBar

したがって、以下はほとんど同じです。

Serializer.Serialize<BaseType>(dest, obj);
...
BaseType obj = Serializer.Deserialize<BaseType>(source);

Serializer.Serialize<DerivedType>(dest, obj);
...
DerivedType obj = Serializer.Deserialize<DerivedType>(source);

ここでの主な違いは、変数の入力方法です。

于 2009-08-17T04:31:08.943 に答える