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