c# - protobuf-net 隐式合约

标签 c# serialization protobuf-net

有没有人有一个可以使用 protobuf-net 作为 BinaryFormatter 的直接替代品的工作示例?这可能吗?

实际上我只需要一个消息类型的序列化程序,看起来像

public class A {
  public B[] Bs { get;set; }
  public C[] Cs { get;set; }
}

所有类型都在不同的程序集中定义,并具有很多属性。 是否有一个选项可以自动生成包含所有公共(public)属性的原型(prototype)契约(Contract),用于 A 类和其他使用的类型(B,C),所以像

var formatter = ProtoBuf.Serializer.CreateFormatter<A>()

能正常工作吗?

最佳答案

首先,protobuf-net 无意也没有声称是 BinaryFormatter 的 100% 替代品。 .它的功能略有不同。

您愿意做一点反射(reflection)吗?基本上,支持 ImplicitFields , 但目前只能通过 [ProtoContract] 获得, 并且不能通过 RuntimeTypeModel 方便地完成,这有点痛苦,并且在我的 list 上。虽然,我应该指出,我认为隐式字段有点冒险,并且只有在您知道 DTO 内部结构不会改变的情况下才应该这样做!但是:要回答您的问题,您可以遍历您期望的类型,然后手动将它们添加到模型中:

static void Main()
{
    Prepare(typeof(A), typeof(B), typeof(C));
    // if you really want to use IFormatter...
    var formatter = RuntimeTypeModel.Default.CreateFormatter(typeof (A));
    var obj = new A {Bs = new B[] {new B()}};
    using (var ms = new MemoryStream())
    {
        formatter.Serialize(ms, obj);
        ms.Position = 0;
        var clone = formatter.Deserialize(ms);
    }
}
static void Prepare(params Type[] types)
{
    if(types != null) foreach(var type in types) Prepare(type);
}
static void Prepare(Type type)
{
    if(type != null && !RuntimeTypeModel.Default.IsDefined(type))
    {
        Debug.WriteLine("Preparing: " + type.FullName);
        // note this has no defined sort, so invent one
        var props = type.GetProperties(); 
        Array.Sort(props, (x, y) => string.Compare(
            x.Name, y.Name, StringComparison.Ordinal));
        var meta = RuntimeTypeModel.Default.Add(type, false);
        int fieldNum = 1;
        for(int i = 0 ; i < props.Length ; i++)
        {
            meta.Add(fieldNum++, props[i].Name);
        }

    }
}

注意使用IFormatter这里完全没有必要;你也可以使用 RuntimeTypeModel.Default.Serialize(...)Serializer.Serialize<T>(...) .

作为脚注:我会建议更多地……重复地定义模型。例如:

RuntimeTypeModel.Default.Add(typeof(A)).Add("Bs", "Cs");
RuntimeTypeModel.Default.Add(typeof(B)).Add("Foo");
RuntimeTypeModel.Default.Add(typeof(C)).Add("Bar", "Blap", "Blop");

关于c# - protobuf-net 隐式合约,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11569593/

相关文章:

c# - 更新一个已经序列化的对象

c# - 如何像字节数组一样处理使用 protobuf 存储的 System.Drawing.Image?

c# - Azure CosmosDB (Gremlin API),如何使用 Gremlin.Net 进行连接

c# - 从我后面的 C# 代码调用 DIV

c# - 如何不根据属性值序列化对象?

java - Spring JsonView 解除嵌套字段

servicestack - protobuf-net 嵌套类支持 ?订单注释?

c# - 具有 Windows 身份验证的 ASP .NET 身份和数据库中的角色

c# - 从 WebAPI Controller 获取声明 - JWT token ,

python - 如何将树类对象结构序列化为JSON文件格式?