/// <summary> /// 将给定的对象转换为给定类型的枚举值。 /// </summary> /// <param name="enumType">枚举对象类型。</param> /// <param name="existingValue">已有的对象。</param> /// <returns></returns> /// <exception cref="ArgumentNullException"> /// <paramref name="enumType"/> 为 null /// 或 /// <paramref name="existingValue"/> 为 null。 /// </exception> /// <exception cref="InvalidOperationException"> /// <paramref name="existingValue"/> 是一个字符串序列但是枚举类型不是 flags 枚举 /// 或 /// 无法将 <paramref name="existingValue"/> 的类型转换到给定的枚举类型。 /// </exception> private static object GetEnumFromExistingValue(Type enumType, object existingValue) { Contract.NotNull(enumType, nameof(enumType)); Contract.NotNull(existingValue, nameof(existingValue)); var enumInfo = EnumInfo.From(enumType); var existingType = existingValue.GetType(); if (existingType.IsEnum) { return(GetEnumFromExistingEnum(enumType, (Enum)existingValue)); } if (existingType == typeof(string)) { return(GetEnumFromExistingString(enumType, (string)existingValue)); } if (existingType.IsPrimitive && existingType != typeof(bool) && existingType != typeof(float) && existingType != typeof(double)) { return(GetEnumFromExistingInteger(enumType, existingValue, enumInfo)); } if (existingType.GetInterfaces().Contains(typeof(IEnumerable <string>))) { return(GetEnumFromExistingStrings(enumType, (IEnumerable <string>)existingValue, enumInfo)); } if (existingValue.GetType().IsSubclassOf(typeof(JToken))) { return(GetEnumFromExistingJToken(enumType, (JToken)existingValue, enumInfo)); } throw new InvalidOperationException( $"Enum of type {enumType} cannot be constructed from object of type {existingType}."); }
/// <inheritdoc /> public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var enumValue = (Enum)value; var enumInfo = EnumInfo.From(enumValue.GetType()); if (!enumInfo.HasFlags(enumValue)) { // enumValue 无法用枚举值进行异或表出。此时应使用 enumValue 的数值进行序列化。 if (enumInfo.IsSigned) { serializer.Serialize(writer, Convert.ToInt64(enumValue)); } else { serializer.Serialize(writer, Convert.ToUInt64(enumValue)); } return; } if (!enumInfo.IsFlags) { serializer.Serialize(writer, enumValue.ToString()); return; } var components = enumInfo.GetComponents(enumValue); if (components.Length == 1) { serializer.Serialize(writer, components[0].ToString()); } else { serializer.Serialize(writer, components.Select(e => e.ToString())); } }