How to serialize arrays?

故事扮演 提交于 2019-12-10 13:56:52

问题


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. e.g.

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?


回答1:


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).




回答2:


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



来源:https://stackoverflow.com/questions/10510589/how-to-serialize-arrays

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!