代码之家  ›  专栏  ›  技术社区  ›  jean

c#protobuf反射用法

  •  2
  • jean  · 技术社区  · 7 年前

    我使用的是官方的c#protobuf(不是protobuf-net)。它是否支持根据其类型创建消息对象?

    典型的反序列化类似于꼚

    MyProtoMessageClass obj = MyProtoMessageClass.Parser.ParseFrom(byteArray);
    

    但是如何根据字符串生成实例

    "MyProtoMessageClass"
    

    或是 Google.Protobuf.Reflection.MessageDescriptor 这是

    MyProtoMessageClass.Descriptor
    

    ?

    更新

    delegate void handler(object data);
    class Wrapper
    {
        public handler h;
        public global::Google.Protobuf.IMessage m;
    }
    Dictionary<ushort, Wrapper> dict = new Dictionary<ushort, Wrapper>();
    
    
    // register
    class HandlerClass {
        public void handle(object o) {
            ProtoMessageClass data = (ProtoMessageClass)o;
            // use data 
        }
    }
    h = HandlerClassObj.handle;
    m = new ProtoMessageClass();
    dict[1] = new Wrapper{h = h, m = m};
    
    // call
    ushort cmd = 1;// from socket
    byte[] dataRecv; // from socket
    var w = dict[cmd];
    Google.Protobuf.IMessage msg = w.m.Descriptor.Parser.ParseFrom(dataRecv);
    w.h.Invoke(msg);
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Ashkan Nourzadeh    7 年前

    假设我们得到了这个原型定义:

    syntax = "proto3";
    package tutorial;
    option csharp_namespace = "T1.Models";
    
    message Person {
        int32 id = 1;
        string name = 2;
    }
    

    编译这个proto文件时,我们得到一个名为 Person 实现 Google.Protobuf.IMessage 。 此接口包含属性 MessageDescriptor Descriptor { get; } ,由类实现 并返回类型为的公共静态属性 MessageDescriptor

    这个 消息描述符 包含名为 Parser ,我们可以调用 ParseFrom(byteArray) 这一点。

    代码:

    var typ = Assembly.GetExecutingAssembly().GetTypes().First(t => t.Name == "Person"); //get the type using the string we got, here it is 'Person'
    var descriptor = (MessageDescriptor)typ.GetProperty("Descriptor", BindingFlags.Public | BindingFlags.Static).GetValue(null, null); // get the static property Descriptor
    var person = descriptor.Parser.ParseFrom(byteArray); // parse the byte array to Person