XmlSerializerを使用する既存のコードをprotobuf-netに移行しようとしていますが、パフォーマンスが向上しているため、この特定のケースで問題が発生しています。
リモートホスト(カスタムミニRPC機能の一種)に送信されるパラメーターを含むobject[]があります。これらのパラメータを使用できるタイプのセットは知っていますが、どの順序で送信されるかを事前に知ることはできません。3つの制約があります。1つ目は、Compact Frameworkで実行しているため、そこで機能するものが必要です。第二に、私が述べたように、パフォーマンスは(シリアル化側で)大きな懸念事項であるため、可能であれば、そこで多くのリフレクションを使用することは避けたいと思います。そして最も重要なのは、このパラメーターが送信された順序を気にすることです。XmlSerializerを使用すると、XmlIncludeを追加するだけで簡単でしたが、Protobuf-netで私が知る限り、フィールドに相当するものはありません。それで、これを行う方法はありますか?これは簡単な例です。
[Serializable]
[XmlInclude(typeof(MyType1)),
XmlInclude(typeof(MyType2)),
XmlInclude(typeof(MyType3))
public class Message()
{
public object[] parameters;
public Message(object[] parms)
{
parameters = parms;
}
}
Message m = new Message(new object[] {MyType1(), 33, "test",
new MyType3(), new MyType3()});
MemoryStream ms = new MemoryStream();
XmlSerializer xml = new XmlSerializer(typeof(Message));
xml.Serialize(ms,xml);
これはXmlSerializerで機能しますが、protobuf-netに変換しようとすると、「オブジェクトのデフォルトのエンコーディングがありません」というメッセージが表示されます。
私が思いついた最善の方法は、この例に示すように、ジェネリックスと[ProtoInclude]を使用することです。配列内にさまざまなオブジェクトタイプを含めることができるので、これではうまくいきません。潜在的なタイプごとにジェネリックリストを追加し、[ProtoIgnore]とタイプobject []のプロパティを追加して、それらを追加して取得しました。それらを追加するときにリフレクションを使用する必要があります(各アイテムを配置する配列を知るため)。これは望ましくありませんが、各リストのすべてのアイテムを1つずつ抽出して、プロパティgetの新しいobject[]配列。
これを達成する方法があるのだろうか?
マークが以下に提案したことを試しましたが、うまくいきませんでした。何か誤解したのではないかと思います。
作成したコードを使用します。MessageParam Createを使用して、リストに追加するMessageParamオブジェクトを生成する必要があると思いました。したがって、基本的に、次のようにメッセージにコンストラクタを追加しました。
public Message(object[] parms)
{
foreach (object o in parms)
{
parameters.Add(MessageParam.Create(o));
}
}
しかし、そうすると、シリアライザーが非ジェネリックバージョンを予期していると想定しているため、「シリアル化中に予期しないタイプが見つかりました。タイプはProtoIncludeAttributeに含まれている必要があります。MessageParam`1がMessageParamとして渡されました」というメッセージが表示されます。私はあなたの提案を誤解しましたか?もしそうなら、何をするのが正しいですか?