-1

I am implementing ISerializer Interface,
in Deserialize method it access generic type which is ProtocolBuffer Class in my case and here i have to Deserialize input string to protocolBuffer Class (Content)

but when i call Content.Parser.ParseFrom i get error saying

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

i cant change Content class to fit my problem since it is generated using ProtoclBuffer Compiler for c# , also i cant change ISerializer since it is vendor library.

so what might be solution here ? how can i call Content.Parser.ParseFrom method

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();
        }
    }
Arash
  • 3,458
  • 7
  • 32
  • 50
  • Possible duplicate of [C# accessing a static property of type T in a generic class](https://stackoverflow.com/questions/7186491/c-sharp-accessing-a-static-property-of-type-t-in-a-generic-class) – Mojtaba Tajik Aug 26 '18 at 05:03
  • @MojtabaTajik , no , not really , – Arash Aug 26 '18 at 05:10

2 Answers2

0

For you deserialization compile time error, the documentation told that you should pass a Func as a function factory to create instances of T to the constructor of MessageParser<T>.

It could be () => new T() or a more complicated function depending on what it's needed to create your messages.

Full code:

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);
    }
}

As the documentation says the serialization should be ok.

Hossein
  • 3,083
  • 3
  • 16
  • 33
0

I think that this answer applies to your case (almost). You can use reflection to invoke the static method like this:

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();
    }
}

You should also use a constraint on your type parameter like shown in the example since you’re calling a method that relies on your generic type being of a class that has a Parser property. In your code snippet, “Content” is a generic type parameter, so I replaced it with T so that it’s not confused with meaning an actual class called “Content”.