Этот вопрос может быть проще всего на конкретном примере. У меня есть класс, представляющий элемент управления, контролируемый игроком в игре. Когда я сериализую это устройство на диск, я хочу сохранить все. Когда я отправляю сетевое обновление другим игрокам, я хочу отправить подмножество "все", включая только те вещи, которые, как я знаю, изменились.
[ProtoContract]
public class Unit
{
[ProtoMember(1, IsRequired=false)
public Vector3 Position;
[ProtoMember(2, IsRequired=false)
public Unit Target;
}
И так далее, все участники помечены как необязательные, поэтому на принимающей стороне он будет надлежащим образом декодировать сообщение независимо от того, содержит ли оно обновление позиции, обновление цели или и то, и другое.
Но.. как я сериализую сообщение, которое не содержит всех участников, помеченных [ProtoMember]?
Имейте в виду, что это произойдет в местах с критическими параметрами производительности, которые также не могут создавать распределения кучи, и мне может потребоваться любая произвольная комбинация различных свойств 20+.
Protobuf-net поддерживает уже существующий шаблон (используемый несколькими другими инструментами сериализации/пользовательского интерфейса):
public bool ShouldSerializeTarget() {...}
public bool ShouldSerializePosition() {...}
Примечание. Методы могут быть частными, за исключением времени выполнения с принудительными проверками доступа.
Что касается контроля опций - я бы, вероятно, использовал перечисление флагов:
return (serializeFlags & UnitMembers.Target) != 0;
С
[Flags]
public enum UnitMembers {
None =0,
Position = 1,
Target = 2,
// 4, 8, 16, 32, etc
}
Это позволяет вам управлять 32 членами в пространстве перечисления int
-based или 64 членами в пространстве long
-based перечисления.