public static bool TryMapToBsonValue(
object value, // will be mapped to an instance of the closest BsonValue class
out BsonValue bsonValue
) {
if (value == null) {
bsonValue = null;
return false;
}
var valueType = value.GetType();
if (valueType.IsEnum) {
valueType = Enum.GetUnderlyingType(valueType);
switch (Type.GetTypeCode(valueType)) {
case TypeCode.Byte: value = (int) (byte) value; break;
case TypeCode.Int16: value = (int) (short) value; break;
case TypeCode.Int32: value = (int) value; break;
case TypeCode.Int64: value = (long) value; break;
case TypeCode.SByte: value = (int) (sbyte) value; break;
case TypeCode.UInt16: value = (int) (ushort) value; break;
case TypeCode.UInt32: value = (long) (uint) value; break;
case TypeCode.UInt64: value = (long) (ulong) value; break;
}
valueType = value.GetType();
}
Conversion conversion;
if (fromMappings.TryGetValue(valueType, out conversion)) {
bsonValue = Convert(value, conversion);
return true;
}
// these mappings can't be handled by the mappings table (because of the interfaces)
if (value is IDictionary) {
bsonValue = new BsonDocument((IDictionary) value);
return true;
}
// NOTE: the check for IEnumerable must be after the check for IDictionary
// because IDictionary implements IEnumerable
if (value is IEnumerable) {
bsonValue = new BsonArray((IEnumerable) value);
return true;
}
ICustomBsonTypeMapper customTypeMapper;
if (customTypeMappers.TryGetValue(valueType, out customTypeMapper)) {
return customTypeMapper.TryMapToBsonValue(value, out bsonValue);
}
bsonValue = null;
return false;
}
#endregion