Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Библиотека protobuf-net — это сериализатор на основе контракта для .NET, использующий двоичный формат сериализации Protocol Buffers . API следует типичным шаблонам .NET и в целом сравним с XmlSerializer и DataContractSerializer.
Некоторые поведения и функции protobuf-net будут заметными во время миграции из BinaryFormatter, и многие сценарии требуют применения атрибутов к элементам.
- По умолчанию как общедоступные, так и не открытые типы сериализуются, при этом сериализатор ожидает конструктора без параметров.
- Protobuf-net требует, чтобы каждый сериализуемый тип был аннотирован с
[ProtoContract]атрибутом. Этот атрибут может при необходимости указатьSkipConstructor = trueсвойство, которое удаляет необходимость в любом конкретном конструкторе. - Каждое сериализуемое нестатическое поле и свойство должно быть аннотировано атрибутом
[ProtoMember(int identifier)]. Имена членов не кодируются в данных. Вместо этого пользователи должны выбрать положительное целое число, чтобы определить каждый элемент, который должен быть уникальным в этом типе. -
Наследование должно быть явно объявлено с помощью
[ProtoInclude(...)]атрибута для каждого типа с известными подтипами. - Поля только для чтения поддерживаются по умолчанию.
- Кроме того, некоторые ненаписанные типы кортежей распознаются шаблоном конструктора; тип с конструктором, который имеет параметры, соответствующие (по имени), все объявленные общедоступные элементы будут интерпретированы как кортеж, и порядок параметров будет использоваться для вывода идентификатора этого элемента.
- Использование пакета времени разработки
protobuf-net.BuildToolsнастоятельно рекомендуется. Это предлагает предупреждения во время компиляции распространенных ошибок.
Пошаговая миграция
- Найдите все сведения об использовании
BinaryFormatter. - Убедитесь, что пути кода сериализации рассматриваются тестами, поэтому вы можете проверить изменения и избежать возникновения ошибок.
- Установите
protobuf-netпакет (и необязательноprotobuf-net.BuildTools). - Найдите все типы, сериализованные с
BinaryFormatterпомощью . - Для типов, которые можно изменить:
- Заметите атрибутом
[ProtoContract]все типы, помеченные или[Serializable]реализующиеISerializableинтерфейс. Если эти типы не предоставляются другим приложениям (например, вы пишете библиотеку), которые могут использовать различные сериализаторы, напримерDataContractSerializer, можно удалить[Serializable]иISerializableзаметки. - Для производных типов применяются
[ProtoInclude(...)]к их базовым типам (см. приведенный ниже пример). - Для каждого типа, объявляющего любой конструктор, принимаюющий параметры, добавьте конструктор без параметров или укажите
SkipConstructor = trueдля атрибута[ProtoContract]. Оставьте комментарий, который объясняет требование protobuf-net (так что никто не удаляет его случайно). - Пометьте все элементы (поля и свойства), с которыми вы хотите сериализовать
[ProtoMember(int identifier)]. Все идентификаторы должны быть уникальными в пределах одного типа, но одни и те же числа можно повторно использовать в подтипах, если наследование включено.
- Заметите атрибутом
- Для типов, которые нельзя изменить:
- Для типов, предоставляемых самим .NET, можно использовать
ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type)API для проверки того, поддерживаются ли они в собственном коде protobuf-net. - Вы можете создать выделенные объекты передачи данных (DTO) и сопоставить их соответствующим образом (для этого можно использовать неявный оператор приведения).
-
RuntimeTypeModelИспользуйте API для определения всех разрешенных атрибутов.
- Для типов, предоставляемых самим .NET, можно использовать
- Замените использование
BinaryFormatterProtoBuf.Serializer.
-[Serializable]
+[ProtoContract]
+[ProtoInclude(2, typeof(Point2D))]
public class Point1D
{
+ [ProtoMember(1)]
public int X { get; set; }
}
-[Serializable]
+[ProtoContract]
public class Point2D : Point1D
{
+ [ProtoMember(2)]
public int Y { get; set; }
}