Ответ 1
Вы не можете определить тип в изоляции, поскольку спецификация protobuf не добавляет никаких данных в поток для этого; однако есть несколько способов сделать это легко, в зависимости от контекста:
- тип объединения (как упоминал Джон) охватывает ряд сценариев
- inheritance (protobuf-net specific) может быть универсальным - вы можете иметь тип базового сообщения и любое количество конкретных типов сообщений
- вы можете использовать префикс для указания входящего типа
последний подход действительно очень ценен в случае необработанных потоков TCP; это на проводе, идентичном типу объединения, но с другой реализацией; заранее определив, что 1 = Foo, 2 = Bar и т.д. (как и для подхода типа объединения), вы можете использовать SerializeWithLengthPrefix
для записи (с указанием номера 1/2/etc в качестве номера поля) -generic TryDeserializeWithLengthPrefix
(это находится в разделе Serializer.NonGeneric в API v1 или в TypeModel в API v2), вы можете предоставить карту типов, которая решает числа обратно к типам и, следовательно, десериализует правильный тип, И чтобы упредить вопрос "почему это полезно в потоках TCP?" - потому что: в текущем потоке TCP вам нужно использовать методы WithLengthPrefix
в любом случае, чтобы избежать чрезмерного чтения потока; поэтому вы можете получить идентификатор типа бесплатно!
Резюме:
- тип объединения: простой в реализации; только нижняя сторона должна затем проверить, какие из свойств не равны нулю.
- Наследование: легко реализовать; может использовать полиморфизм или дискриминатор для обработки "что теперь?" Префикс типа
- : немного более сложно реализовать, но обеспечивает большую гибкость и имеет нулевые накладные расходы в потоках TCP.