Tôi đã sử dụng CustomEnumSerializer để xử lý thuộc tính EnumMember
public class CustomEnumSerializer : StructSerializerBase, IRepresentationConfigurable where TEnum : struct
{
private static readonly Dictionary _fromValueMap = new Dictionary[]; // string representation to Enum value map
private static readonly Dictionary _toValueMap = new Dictionary[]; // Enum value to string map
// private fields
private readonly BsonType _representation;
// constructors
///
/// Initializes a new instance of the class.
///
public CustomEnumSerializer[]
: this[[BsonType]0] // 0 means use underlying type
{
}
///
/// Initializes a new instance of the class.
///
/// The representation.
public CustomEnumSerializer[BsonType representation]
{
switch [representation]
{
case 0:
case BsonType.Int32:
case BsonType.Int64:
case BsonType.String:
break;
default:
var message = string.Format["{0} is not a valid representation for an EnumSerializer.", representation];
throw new ArgumentException[message];
}
// don't know of a way to enforce this at compile time
var enumTypeInfo = typeof[TEnum].GetTypeInfo[];
if [!enumTypeInfo.IsEnum]
{
var message = string.Format["{0} is not an enum type.", typeof[TEnum].FullName];
throw new BsonSerializationException[message];
}
_representation = representation;
if [representation == BsonType.String]
{
var enumType = typeof[TEnum];
if [!_fromValueMap.ContainsKey[enumType]]
{
Dictionary fromMap = new Dictionary[StringComparer.InvariantCultureIgnoreCase];
Dictionary toMap = new Dictionary[];
FieldInfo[] fields = enumType.GetFields[BindingFlags.Static | BindingFlags.Public];
foreach [FieldInfo field in fields]
{
string name = field.Name;
object enumValue = Enum.Parse[enumType, name];
// use EnumMember attribute if exists
EnumMemberAttribute enumMemberAttrbiute = field.GetCustomAttribute[];
if [enumMemberAttrbiute != null]
{
string enumMemberValue = enumMemberAttrbiute.Value;
fromMap[enumMemberValue] = enumValue;
toMap[enumValue] = enumMemberValue;
}
else
{
toMap[enumValue] = name;
}
fromMap[name] = enumValue;
}
_fromValueMap[enumType] = fromMap;
_toValueMap[enumType] = toMap;
}
}
}
// public properties
///
/// Gets the representation.
///
///
/// The representation.
///
public BsonType Representation
{
get { return _representation; }
}
// public methods
///
/// Deserializes a value.
///
/// The deserialization context.
/// The deserialization args.
/// A deserialized value.
public override TEnum Deserialize[BsonDeserializationContext context, BsonDeserializationArgs args]
{
var bsonReader = context.Reader;
var bsonType = bsonReader.GetCurrentBsonType[];
switch [bsonType]
{
case BsonType.Int32: return [TEnum]Enum.ToObject[typeof[TEnum], bsonReader.ReadInt32[]];
case BsonType.Int64: return [TEnum]Enum.ToObject[typeof[TEnum], bsonReader.ReadInt64[]];
case BsonType.Double: return [TEnum]Enum.ToObject[typeof[TEnum], [long]bsonReader.ReadDouble[]];
case BsonType.String:
var fromValue = FromValue[typeof[TEnum], bsonReader.ReadString[]];
return [TEnum]Enum.Parse[typeof[TEnum], fromValue.ToString[]];
default:
throw CreateCannotDeserializeFromBsonTypeException[bsonType];
}
}
///
/// Serializes a value.
///
/// The serialization context.
/// The serialization args.
/// The object.
public override void Serialize[BsonSerializationContext context, BsonSerializationArgs args, TEnum value]
{
var bsonWriter = context.Writer;
switch [_representation]
{
case 0:
var underlyingTypeCode = Type.GetTypeCode[Enum.GetUnderlyingType[typeof[TEnum]]];
if [underlyingTypeCode == TypeCode.Int64 || underlyingTypeCode == TypeCode.UInt64]
{
goto case BsonType.Int64;
}
else
{
goto case BsonType.Int32;
}
case BsonType.Int32:
bsonWriter.WriteInt32[Convert.ToInt32[value]];
break;
case BsonType.Int64:
bsonWriter.WriteInt64[Convert.ToInt64[value]];
break;
case BsonType.String:
var val = ToValue[typeof[TEnum], value];
bsonWriter.WriteString[val];
break;
default:
throw new BsonInternalException["Unexpected EnumRepresentation."];
}
}
private string ToValue[Type enumType, object obj]
{
Dictionary map = _toValueMap[enumType];
return map[obj];
}
private object FromValue[Type enumType, string value]
{
Dictionary map = _fromValueMap[enumType];
if [!map.ContainsKey[value]]
return value;
return map[value];
}
///
/// Returns a serializer that has been reconfigured with the specified representation.
///
/// The representation.
/// The reconfigured serializer.
public CustomEnumSerializer WithRepresentation[BsonType representation]
{
if [representation == _representation]
{
return this;
}
else
{
return new CustomEnumSerializer[representation];
}
}
// explicit interface implementations
IBsonSerializer IRepresentationConfigurable.WithRepresentation[BsonType representation]
{
return WithRepresentation[representation];
}
}
0 hữu ích 0 bình luận chia sẻ 0 bình luận chia sẻ