1

protobuf-net を使用して、別のカスタム クラス (MessageArguments と呼ばれる) のリストを含むクラス (RPCMessage と呼ばれる) を送信しようとしています。MessageArguments を拡張して、引数を希望する値の型 (この場合は float) に基づいて異なるクラスを持つようにしました。次の例外が発生しています: ArgumentNullException: 既知の型を空白にすることはできません。それが役立つ場合、私は.Net 3.5を使用しています。

シリアル化するコード:

public static void EncodeMessage(MessageType messageType, object messageClass, ref NetOutgoingMessage outMessage){
    byte[] serialised;

    var serializableObject = messageClass as RPCMessage;
    var memStream = new MemoryStream();
    Serializer.SerializeWithLengthPrefix(memStream, serializableObject,
    PrefixStyle.Base128);       
}

メッセージを保存するコード:

[Serializable,
ProtoContract,
ProtoInclude(3, typeof(FloatArgument))]
public class RPCMessage {
    [ProtoMember(1)]
    public byte code;
    [ProtoMember(2)]
    public List<MessageArgument> args;

    public RPCMessage(){}

    public RPCMessage (byte _code, List<MessageArgument> _args){
        code = _code;
        args = _args;
    }
}

メッセージ引数を格納するコード:

[Serializable,
ProtoContract,
ProtoInclude(3, typeof(FloatArgument)))]
public class MessageArgument{
    [ProtoMember(1)]
    public byte id; 

    public MessageArgument(){}

    public MessageArgument(byte _id){
        id = _id;
    }
}

そして最後に、によって呼び出されます

List<MessageArgument> args = new List<MessageArgument>();
args.Add(new FloatArgument(0, 1f));
MessageParser.EncodeMessage(type, new RPCMessage(0, args), ref outMessage);

私はおそらく何か基本的なものが欠けていることを知っていますが、それが何であるかを一生理解することはできません

4

1 に答える 1

0

完全に再現するのに十分ではありませんが、いくつかの観察:

  • [ProtoInclude]継承階層を表します。がとFloatArgumentの両方から派生することはあり得ないので、(命名により) の包含が正しくなく、削除する必要があると想定します。MessageArgumentRPCMessageRPCMessage
  • object使用しているため、汎用 API は使用できません。代わりに試してください:

    Serializer.NonGeneric.SerializeWithLengthPrefix(memStream,
         serializableObject, PrefixStyle.Base128, 1);
    

これにより、シリアル化とクローンが正常に実行されます。

于 2012-05-09T09:39:23.053 に答える