вызов статического метода общего типа в c # - PullRequest
0 голосов
/ 26 августа 2018

Я использую Интерфейс ISerializer ,в методе десериализации он обращается к универсальному типу, который в моем случае является классом ProtocolBuffer, и здесь я должен десериализовать входную строку в класс protocolBuffer (Content)

, но когда я вызываю Content.Parser.ParseFrom, я получаю сообщение об ошибке

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

Я не могу изменить класс содержимого, чтобы он соответствовал моей проблеме, поскольку он генерируется с помощью компилятора ProtoclBuffer для 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 голосов
/ 26 августа 2018

Я думаю, что этот ответ относится к вашему делу (почти).Вы можете использовать рефлексию для вызова статического метода следующим образом:

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».

0 голосов
/ 26 августа 2018

Для ошибки десериализации при компиляции в документации сказано, что вам следует передать 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);
    }
}

Как указано в документации , сериализация должна быть в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...