在c#

时间:2018-08-26 04:41:09

标签: c# protocol-buffers

我正在实现 ISerializer 接口,
 在反序列化方法中,它访问通用类型 在我的情况下是ProtocolBuffer类,在这里我必须将输入字符串反序列化为protocolBuffer类(内容)

但是当我致电Content.Parser.ParseFrom时,我得到了错误提示

'Content' is type parameter which is not valid in given context;

我无法更改Content类以适应我的问题,因为它是使用ProtoclBuffer Compiler for c#生成的,我也不能更改 ISerializer ,因为它是供应商库。

那么这里可能有什么解决方案?如何调用 Content.Parser.ParseFrom 方法

class PBFSerializer : ISerializer
    {

        public Content Deserialize<Content>(string json)
        {
            byte[] byteArray = Encoding.UTF8.GetBytes(json);

            return Content.Parser.ParseFrom(byteArray);
            //'Content' is type parameter which is not valid in given context;
        }

        public byte[] Serialize(object obj)
        {
                var content = (Content)obj;
                return content.ToByteArray();
        }
    }

2 个答案:

答案 0 :(得分:0)

对于反序列化编译时错误,documentation告知您应该通过 Func 作为函数工厂来创建的实例 T MessageParser<T>的构造函数。

根据创建消息所需的功能,它可以be () => new T()或更复杂的功能。

完整代码:

public static T Deserialize<T>(byte[] buf) where T : IMessage<T>, new()
{
    if (buf == null)
        return default(T);

    using (MemoryStream ms = new MemoryStream())
    {
        ms.Write(buf, 0, buf.Length);
        ms.Seek(0, SeekOrigin.Begin);

        MessageParser<T> parser = new MessageParser<T>(() => new T());
        return parser.ParseFrom(ms);
    }
}

正如documentation所说,序列化应该可以。

答案 1 :(得分:0)

我认为this answer适用于您的情况(几乎)。您可以使用反射来调用静态方法,如下所示:

class PBFSerializer : ISerializer
{

    public T Deserialize<T>(string json) where T : someParentClass
    {
        byte[] byteArray = Encoding.UTF8.GetBytes(json);

        FieldInfo field = typeof(T).GetField(“Parser”);
        T result = field.FieldType.GetMethod(“ParseFrom”).Invoke(null, new object[]{byteArray});

        return result;
    }

    public byte[] Serialize<T>(object obj) where T : someParentClass
    {
            T content = (T)obj;

            return T.ToByteArray();
    }
}

您还应该对类型参数使用约束,如示例中所示,因为您要调用的方法依赖于您的泛型类型属于具有Parser属性的类。在您的代码段中,“ Content”是一个泛型类型参数,因此我将其替换为T,以免将其与实际名为“ Content”的类混淆。