简体   繁体   中英

How to serialize arrays?

Symptom: No serializer defined for type: System.Array

Since all C# arrays inherit from the Array class, I thought that this would be valid in ProtoBuf-net

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

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

Should I register Array with the RuntimeTypeModel?

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

Attempts:

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

Another possible solution (can't find the SO url right now):

Have a list of a base type class items.

Wrap each type. eg

class TheBase{}

class ArrayOfInt { public int[] value;}

The would then become one of converting to and from a list of wrappers. Is there an easier way forward?

protobuf-net really really wants to understand the data you are serializing; it isn't enough to have Array , as that can't map to any protobuf definition. Repeated data (conceptually, arrays) has a very terse and very specific representation in the protobuf specification, which does not allow extra room for saying, on an individual basis, "of [x]". In protobuf, the "of [x]" is expected to be already known and fixed in advance .

So:

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

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

will work fine. But Array will not work at all.

Depending on how important this is, there may be other options, for example (and you may want to tweak the names!):

[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); } }
}

with:

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

would work, I suspect (untested). With classes, there is a little extra room that protobuf-net can use to implement inheritance (which also, technically, isn't supported in the protobuf specification - this is a shim that protobuf-net squeezes in).

Why don't you try creating a new ISerializable object like this

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

and override the GetObjectData() from the interface ISerializable

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM