c# - protobuf-net:无法序列化类型数据,如何使用 Protocol Buffer 定义类型数据?

标签 c# protocol-buffers protobuf-net

我正在尝试创建一个简单的内存网格,它可以使用 Protocol Buffer 进行序列化。

想法是用户可以创建/定义任何类型的列(基元或用户定义的,只要它们带有 Protocol Buffer 标记)。

我的问题是您不能使用 Protocol Buffer 序列化类型数据,那么我该如何实现呢?

下面的代码显示了我希望如何对网格的列进行编码。

非常感谢。

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Column colOrderId = new Column("OrderId", typeof(uint));
        Column colOrderDesc = new Column("OrderDesc", typeof(string));
        Column colPrice = new Column("Price", typeof(Price));
        Column colOrderDateTime = new Column("OrderDateTime", typeof(DateTime));

        var s = colOrderId.ToBArray();
    }
}

[ProtoContract, Serializable]
public sealed class Column
{
    public Column(string name, Type type)
    {
        Name = name;
        Type = type;
    }

    [ProtoMember(1)]
    public string Name { get; private set; }

    [ProtoMember(2)]
    public Type Type { get; private set; }
}

[ProtoContract, Serializable]
public sealed class Price
{
    public Price(double value, string currency)
    {
        Value = value;
        Currency = currency;
    }

    [ProtoMember(1)]
    public double Value { get; private set; }

    [ProtoMember(2)]
    public string Currency { get; private set; }
}

public static class ProtoBufEx
{
    public static byte[] ToBArray<T>(this T o)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            ProtoBuf.Serializer.Serialize(ms, o);
            return ms.ToArray();
        }
    }
}

最佳答案

这种方法有几个问题;是的,在标准 Protocol Buffer 中,任何类型的 Type 元数据都有点顽皮,因为它并不是真正可互操作的,但我在 v2 中选择加入的基础上玩得有点松散 - 允许您发送 object 等,只要它在内部仍然知道您的意思。

然而,这对于逐个单元的工作来说会变得昂贵,即使内置了优化(例如,它只发送一次相同类型的元数据)。

不过,在 IMO 中,一个更好的选择是将自己限制在一个已知类型的列表中,这些类型都是提前已知的。如果您能做到,那么有一些有趣的继承技巧非常有效并且非常适合这种情况。但本质上你会有类似的东西:

[ProtoContract]
[ProtoInclude(4, typeof(Column<int>))] // etc
abstract class Column {
    [ProtoMember(1)]
    public string Name {get;private set;}

    public abstract object Value {get;private set;}
}
[ProtoContract]
class Column<T> : Column {
    [ProtoMember(1)]
    public T TypedValue { get;private set;}
    override Value {...shim to TypedValue...}
}
// etc

(伪代码,不完整)

我很乐意向您介绍其中的很多内容,但您可能还想看看 this blog entry看看使用 DataTable(因为我不喜欢它进行数据访问)是否可以在这里节省一些精力。

关于c# - protobuf-net:无法序列化类型数据,如何使用 Protocol Buffer 定义类型数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6498438/

相关文章:

c# - Nullable<> 类型是 BCL、CLR 还是两者的实现?

c# - WPF 绑定(bind)源

java - 自定义 mapstruct 以忽略 protobuff 字段

crash - 仅在 GDB 中调用的纯虚方法

c# - protobuf-net 的 DeepClone 问题 - 使用枚举

c# - ASP.net MVC 嵌套模型显示名称

c# - WCF 服务不返回 GET 方法不允许的方法

Java、GTFS Realtime、protocol buffers,简单搞定?

c# - 使用 ProtoBuff.Net 通过 Socket 接收多种类型的对象

c# - 我在反序列化过程中遇到下一个异常 : "Invalid field in source data: 0". 如何找出源代码中的原因/错误位置?