No se puede detectar el tipo de forma aislada, ya que la especificación protobuf no agrega ningún dato a la secuencia para esto; Sin embargo, hay un número de maneras de hacer esto fácil, dependiendo del contexto:
- un tipo de unión (como se ha mencionado por Jon) abarca una gama de escenarios
- herencia (específico para protobuf neto) puede ser versátil - puede tener un tipo de mensaje base, y cualquier número de tipos de mensajes concretos
- puede utilizar un prefijo para indicar el tipo de entrada
el último enfoque es realmente muy valioso en el caso de TCP prima corrientes; esto es en el cable idéntico al tipo de unión, pero con una implementación diferente; decidiendo de antemano que 1 = Foo, 2 = Bar, etc. (exactamente como lo hace para el enfoque de tipo de unión), puede usar SerializeWithLengthPrefix
para escribir (especificando el 1/2/etc como el número de campo), y el no genérico TryDeserializeWithLengthPrefix
para leer (esto es en Serializer.NonGeneric en v1 API, o en TypeModel en v2 API), puede proporcionar un mapa de tipos que resuelve los números a tipos y, por lo tanto, deserializa el tipo correcto. Y para adelantarse a la pregunta "¿por qué es esto útil con las transmisiones TCP?" - porque: en una corriente TCP en curso, usted necesita para usar los métodos WithLengthPrefix
de todos modos, para evitar leer en exceso la transmisión; así que es mejor que obtengas el identificador de tipo gratis!
Resumen:
- tipo de unión: fácil de implementar; el único inconveniente es tener que verificar cuál de las propiedades es no nula
- herencia: fácil de implementar; puede usar polimorfismo o discriminador para manejar "¿y ahora qué?"
- prefijo de tipo: un poco más complicados de implementar, pero permite una mayor flexibilidad, y tiene cero sobrecarga en flujos TCP
Solo utilizaría múltiples puntos finales. La sobrecarga de funciones es lo suficientemente torpe en los lenguajes de programación, y mucho menos en los servicios de red. – millimoose
Gracias, este es mi plan de copia de seguridad :) –