Официальный драйвер C # будет записывать значение дискриминатора "_t" всякий раз, когда фактический тип объекта отличается от номинального типа.Так, например:
MyRootClass obj = new MyDerivedClass();
collection.Insert(obj);
Можно также написать оператор Insert:
collection.Insert<MyRootClass>(obj);
, но компилятору проще выводить параметр типа.
Так какфактический тип obj отличается от номинального типа, на котором будет записан дискриминатор "_t".
При чтении объекта вам необходимо убедиться, что MyDerivedClass был правильно зарегистрирован:
BsonClassMap.RegisterClassMap<MyDerivedClass>();
или сериализатор не распознает дискриминатор (это может показаться ограничением, но логично, что сериализатор может работать только с типами, о которых он знает).
Вы упомянули, что не знаетеклассы во время компиляции, поэтому приведенный выше регистрационный код должен вызываться динамически.Один из способов сделать это:
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]);
Технически, сериализация не использует отражение;это метаданные.Отражение используется один раз для построения карты классов, но после этого карта классов используется напрямую без отражения, и накладные расходы довольно низкие.