7

症状: 次のタイプのシリアライザーが定義されていません: System.Array

C# の配列はすべて Array クラスを継承しているので、ProtoBuf-net ではこれが通用すると思った

[ProtoMember(1)]
public Array SomeKindOfArray = new int[]{1,2,3,4,5};

[ProtoMember(2)]
public List<Array> SomeKindOfList = new List<Array>();

Array を RuntimeTypeModel に登録する必要がありますか?

m.Add(typeof (Array), true);  // does not seem to help

試み:

new int[]{1,2,3,4} // works

(object)new int[] { 1, 2, 3, 4 } // does not work

(Array)new int[] { 1, 2, 3, 4 } // does not work

別の可能な解決策(現在SOのURLが見つかりません):

基本型クラス アイテムのリストを用意します。

種類ごとに包みます。例えば

class TheBase{}

class ArrayOfInt { public int[] value;}

は、ラッパーのリストとの間の変換の 1 つになります。もっと簡単な方法はありますか?

4

2 に答える 2

13

protobuf-net は、シリアライズしているデータを本当に理解したいと思っています。を持っているだけでは十分ではありません。これはArray、protobuf 定義にマップできないためです。繰り返されるデータ (概念的には配列) は、protobuf 仕様で非常に簡潔で非常に具体的な表現を持ってます。protobuf では、「[x] の」は既知であり、事前に修正されていることが期待されます。

そう:

[ProtoMember(1)]
public int[] AnIntegerArray {get;set;}

[ProtoMember(2)]
public Customer[] ACustomerArray {get;set;}

うまくいきます。しかし、Arrayまったく機能しません。

これがどれほど重要かによって、他のオプションがあるかもしれません。

[ProtoContract]
[ProtoInclude(1, typeof(DummyWrapper<int>)]
[ProtoInclude(2, typeof(DummyWrapper<Customer>)]
public abstract class DummyWrapper {
    public abstract Type ElementType {get;}
}
[ProtoContract]
public class DummyWrapper<T> : DummyWrapper {
    [ProtoMember(1)]
    public T[] TheData {get;set;}

    public override Type ElementType {get { return typeof(T); } }
}

と:

[ProtoMember(1)]
public DummyWrapper TheData {get;set;}

うまくいくと思います(テストされていません)。クラスを使用すると、protobuf-net が継承を実装するために使用できる少し余裕があります (また、技術的には、protobuf 仕様ではサポートされていません。これは、protobuf-net が押し込むシムです)。

于 2012-05-09T06:12:42.363 に答える
-1

このような新しい ISerializable オブジェクトを作成してみませんか

[Serializable()]    
public class ArrayOfInt : ISerializable 
{
    public Array ....etc

インターフェイス ISerializable から GetObjectData() をオーバーライドします。

于 2012-05-09T06:12:25.063 に答える