Официальный драйвер 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]);
Технически сериализация не использует отражение; это управляется метаданными. Отражение используется один раз для построения карты классов, но после этого карта классов используется напрямую без отражения, и накладные расходы довольно низки.
person
Robert Stam
schedule
08.06.2011