Exemplo n.º 1
0
        /// <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}.");
        }
Exemplo n.º 2
0
        /// <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()));
            }
        }