El controlador oficial C# escribirá un valor de discriminador "_t" siempre que el tipo real de un objeto sea diferente del tipo nominal. Así, por ejemplo:
MyRootClass obj = new MyDerivedClass();
collection.Insert(obj);
La sentencia Insert también podría haberse escrito:
collection.Insert<MyRootClass>(obj);
pero es más fácil dejar que el compilador inferir el parámetro de tipo.
Dado que el tipo real de obj es diferente del tipo nominal, se escribirá el discriminador "_t".
Al leer hacia atrás el objeto que tendrá que asegurarse de que MyDerivedClass se ha registrado correctamente:
BsonClassMap.RegisterClassMap<MyDerivedClass>();
o el serializador no reconocerá el discriminador (esto puede parecer como una restricción, pero es lógico que el serializador solo puede funcionar con tipos que conoce).
Mencionó que no conoce las clases en tiempo de compilación, por lo que el código de registro anterior debe invocarse dinámicamente. Una forma de hacerlo es:
Type myDerivedClass; // your plugged-in class
var registerClassMapDefinition = typeof(BsonClassMap).GetMethod("RegisterClassMap", new Type[0]);
var registerClassMapInfo = registerClassMapDefinition.MakeGenericMethod(myDerivedClass);
registerClassMapInfo.Invoke(null, new object[0]);
Técnicamente, la serialización no está utilizando la reflexión; es impulsado por metadatos. La reflexión se usa una vez para construir el mapa de clase, pero después de eso, el mapa de clase se usa directamente sin reflexión, y la sobrecarga es bastante baja.
Gracias mucho. Exactamente lo que estaba buscando. –
Muy buena respuesta, la única que encontré completa para deserializar clases desconocidas en tiempo de compilación. –