在下面的例子:

public class RowData
{
    public object[] Values;
}

public class FieldData
{
    public object Value;
}

我很好奇如何或者格式网或dotnet-protobufs会处理这样的课程。我更熟悉的格式网络,那么,其实,我有的是:

[ProtoContract]
public class RowData
{
    [ProtoMember(1)]
    public object[] Values;
}
[ProtoContract]
public class FieldData
{
    [ProtoMember(1)]
    public object Value;
}

但是我得到一个错误的说法"没有合适的默认对象编码找到"。是有一个简单的方法来对待这些类别,我只是不知道的吗?

拟订更多关于使用情况:

这是一个缩减版本的数据类使用远程处理。所以基本上它看起来像这样:

FieldData data = new FieldData();
data.Value = 8;

remoteObject.DoSomething(data);

注:我省略了该法的实施于简单,但它是为你所期望的。

有帮助吗?

解决方案

(更新)

权利;想通了...主要的问题在我的样本上的价值-干将;他们扔的例外情况。也有一些图书馆故障(现在固定).

但是,最简单的方法是 Nullable<T> 通过性质:

    [ProtoMember(1)]
    private int? ValueInt32
    {
        get { return Get<int>(); }
        set { Value = value; }
    }

等等,具有:

    private T? Get<T>() where T : struct
    {
        return (Value != null && Value is T) ? (T?)Value : (T?)null;
    }

这两个与*指定的做法已经 测试, 和现在的工作的罚款。

其他提示

重新protobuf网,这是我维持:

这里的问题是不是值类型(它通常会处理细) - 它是开放object使用,这意味着它根本不知道什么数据预期,因此如何编码/解码。

目前,我想不出一个简单/干净的方法来处理这个问题。它会处理的范围内的共同值型方案,列表和基于合同(数据契约,原合同,或一些XML的模式)的层次结构的任何电平,但它需要一个线索

或许,如果你能澄清的用例,我也许能帮助更多?例如,上述将不会很与DataContractSerializerXmlSerializer工作,要么...

重新DOTNET-protobufs;我真的不能评论,但我敢肯定,这将是更不宽容;它的目的是用来自.proto文件生成的类使用,所以object就根本不会进入模型(乔恩:纠正我,如果我错了)

如果你决定把更多的信息,您可以在这里善意发表评论?因此,我可以很容易找到它......或者,直接给我发邮件(见我的SO配置文件)。


编辑 - 这是我脑子里想的哈克的东西 - 它不是在工作的时刻,但我会找出原因明天(可能)。需要注意的是在理论上额外的成员都可能是私人 - 我只是想,以方便在调试。请注意,这并不需要任何额外的存储空间。就像我说的,今天不上班,但它应该 - 我会找出原因...

[ProtoContract]
public class FieldData
{
    public object Value {get;set;}

    [ProtoMember(1)]
    public int ValueInt32 {
        get { return (int)Value; } set { Value = value; } }
    public bool ValueInt32Specified {
        get { return Value != null && Value is int; } set { } }

    [ProtoMember(2)]
    public float ValueSingle {
        get { return (float)Value; } set { Value = value; } }
    public bool ValueSingleSpecified {
        get { return Value != null && Value is float; } set { } }

    // etc for expected types
}

这是什么像什么,我的初衷。让我知道你的想法。当然,我不得不增加一个子类,每个值类型我需要支持。你怎么看?有没有更好的办法,你看不到任何低效用这种方法?

[ProtoContract, Serializable]
[ProtoInclude(1, typeof(Int32FieldData))]
public abstract class FieldDataBase : ISerializable
{
    [ProtoIgnore]
    public abstract object Value { get; set;}
    protected FieldDataBase()
    { }

    #region ISerializable Members
    protected FieldDataBase(SerializationInfo info, StreamingContext context)
    {
        Serializer.Merge<FieldDataBase>(info, this);
    }
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        Serializer.Serialize<FieldDataBase>(info, this);
    }

    #endregion
}

[ProtoContract, Serializable]
public class Int32FieldData : FieldDataBase
{
    [ProtoMember(1)]
    public int? Int32Value;

    [ProtoIgnore]
    public override object Value
    {
        get { return this.Int32Value.HasValue ? this.Int32Value : null; }
        set { this.Int32Value = (int?)value; }
    }
    public Int32FieldData() { }
    protected Int32FieldData(SerializationInfo info, StreamingContext context)
        :base(info, context)
    { }
}

直接封装似乎没有额外的开销很好地工作,从所有的属性,以下面的方式:

[ProtoContract, Serializable]
public class ObjectWrapper : ISerializable
{
    public ObjectWrapper()
    { }
    [ProtoIgnore]
    public object Value
    {
        get
        {
            if (Int32Value.HasValue)
                return Int32Value.Value;
            else if (BinaryValue != null)
                return BinaryValue;
            else
                return StringValue;
        }
        set
        {
            if (value is int)
                this.Int32Value = (int)value;
            else if (value is byte[])
                this.BinaryValue = (byte[])value;
            else if (value is string)
                this.StringValue = (string)value;
        }
    }
    [ProtoMember(1)]
    private int? Int32Value;
    [ProtoMember(2)]
    private string StringValue;
    [ProtoMember(3)]
    private byte[] BinaryValue;
            // etc

    #region ISerializable Members
    protected ObjectWrapper(SerializationInfo info, StreamingContext context)
    {
        Serializer.Merge<ObjectWrapper>(info, this);
    }
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        Serializer.Serialize<ObjectWrapper>(info, this);
    }

    #endregion
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top