Protobuf-net. Десериализовать на основе

Допустим, у нас есть следующие три класса:

[ProtoContract]
[ProtoInclude(10, typeof(FirstType))]
[ProtoInclude(20, typeof(SecondType))]
public class Base
{
    [ProtoMember(1)]
    public int ClassId {get;set;}
}

public class FirstClass : Base
{
    ...
}

public class SecondClass : Base
{
   ...
}

И есть связь между идентификатором класса (в базовом классе) и типом соответствующего дочернего класса. Например,

var obj1 = new FirstClass() {ClassId = 1}
var obj2 = new SecondClass() {ClassId = 2}

Теперь давайте предположим, что мы сериализовали эти объекты. Вопрос в следующем: есть ли хороший способ десериализовать сериализованный protobuf на основе значения идентификатора класса, просматривая поле ClassId? т. е. если значение classId в serailized protobuf равно 1, то используйте FirstClass для десериализации оставшихся байтов потока.

Благодарность!


person soleiljy    schedule 14.02.2013    source источник


Ответы (1)


Если вы используете ProtoInclude, то protobuf-net уже позаботится о том, какой подкласс использовать: в этом весь пункт ProtoInclude. В некоторых случаях невозможно использовать наследование, и в этом случае есть способы прочитать прото-поток либо через ProtoReader, либо с помощью второй модели, которая только читает это свойство, затем сбрасывает источник и снова читает. Пример этого здесь: https://stackoverflow.com/a/14572685/23354

person Marc Gravell    schedule 14.02.2013
comment
спасибо за ваши ответы! еще вопрос: способ чтения протопотока через ProtoReader очень интересен. Похоже, я могу создать свой собственный преобразователь (например, JsonConverter в Json.Net), который будет использоваться при десериализации. В Protobuf-net есть ли способ передать такой пользовательский преобразователь, чтобы при распечатывании объектов можно было использовать этот пользовательский преобразователь вместо стандартного? - person soleiljy; 15.02.2013
comment
@soleiljy определить собственный конвертер в этом контексте? ProtoReader и ProtoWriter - это то, что сериализатор использует под капотом, однако они не настраиваются. Существует только один способ чтения базового потока. Если вы имеете в виду, что я могу написать свой собственный движок поверх ProtoReader — конечно: получайте удовольствие. Пример пользовательского сериализатора DataTable приведен здесь: code.google. com/p/protobuf-net/source/browse/trunk/ - person Marc Gravell; 15.02.2013