InternalGetUnderlyingType() private method

private InternalGetUnderlyingType ( Type enumType ) : Type
enumType Type
return Type
コード例 #1
0
        public sealed override Array GetEnumValues()
        {
            if (!IsEnum)
            {
                throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
            }

            Array values = Enum.GetEnumInfo(this).ValuesAsUnderlyingType;
            int   count  = values.Length;
            // Without universal shared generics, chances are slim that we'll have the appropriate
            // array type available. Offer an escape hatch that avoids a MissingMetadataException
            // at the cost of a small appcompat risk.
            Array result;

            if (AppContext.TryGetSwitch("Switch.System.Enum.RelaxedGetValues", out bool isRelaxed) && isRelaxed)
            {
                result = Array.CreateInstance(Enum.InternalGetUnderlyingType(this), count);
            }
            else
            {
                result = Array.CreateInstance(this, count);
            }
            Array.Copy(values, result, values.Length);
            return(result);
        }
コード例 #2
0
        public sealed override bool IsEnumDefined(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            if (!IsEnum)
            {
                throw new ArgumentException(SR.Arg_MustBeEnum);
            }

            if (value is string valueAsString)
            {
                EnumInfo enumInfo = Enum.GetEnumInfo(this);
                foreach (string name in enumInfo.Names)
                {
                    if (valueAsString == name)
                    {
                        return(true);
                    }
                }
                return(false);
            }
            else
            {
                ulong rawValue;
                if (!Enum.TryGetUnboxedValueOfEnumOrInteger(value, out rawValue))
                {
                    if (Type.IsIntegerType(value.GetType()))
                    {
                        throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, value.GetType(), Enum.InternalGetUnderlyingType(this)));
                    }
                    else
                    {
                        throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
                    }
                }

                if (value is Enum)
                {
                    if (!Enum.ValueTypeMatchesEnumType(this, value))
                    {
                        throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, value.GetType(), this));
                    }
                }
                else
                {
                    Type underlyingType = Enum.InternalGetUnderlyingType(this);
                    if (!(underlyingType.TypeHandle.ToEETypePtr() == value.EETypePtr))
                    {
                        throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, value.GetType(), underlyingType));
                    }
                }

                return(Enum.GetEnumName(this, rawValue) != null);
            }
        }
コード例 #3
0
ファイル: RuntimeType.cs プロジェクト: mikem8361/runtime
        public override Type GetEnumUnderlyingType()
        {
            if (!IsActualEnum)
            {
                throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
            }

            return(Enum.InternalGetUnderlyingType(this));
        }
コード例 #4
0
        public override bool IsEnumDefined(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            if (!IsEnum)
            {
                throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
            }

            // Check if both of them are of the same type
            RuntimeType valueType = (RuntimeType)value.GetType();

            // If the value is an Enum then we need to extract the underlying value from it
            if (valueType.IsEnum)
            {
                if (!valueType.IsEquivalentTo(this))
                {
                    throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType, this));
                }

                valueType = (RuntimeType)valueType.GetEnumUnderlyingType();
            }

            // If a string is passed in
            if (valueType == StringType)
            {
                // Get all of the Fields, calling GetHashEntry directly to avoid copying
                string[] names = Enum.InternalGetNames(this);
                return(Array.IndexOf(names, value) >= 0);
            }

            // If an enum or integer value is passed in
            if (IsIntegerType(valueType))
            {
                RuntimeType underlyingType = Enum.InternalGetUnderlyingType(this);
                if (underlyingType != valueType)
                {
                    throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, valueType, underlyingType));
                }

                ulong[] ulValues = Enum.InternalGetValues(this);
                ulong   ulValue  = Enum.ToUInt64(value);

                return(Array.BinarySearch(ulValues, ulValue) >= 0);
            }
            else
            {
                throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
            }
        }
コード例 #5
0
ファイル: RuntimeType.cs プロジェクト: mikem8361/runtime
        protected override TypeCode GetTypeCodeImpl()
        {
            TypeCode typeCode = Cache.TypeCode;

            if (typeCode != TypeCode.Empty)
            {
                return(typeCode);
            }

            CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(this);

            switch (corElementType)
            {
            case CorElementType.ELEMENT_TYPE_BOOLEAN:
                typeCode = TypeCode.Boolean; break;

            case CorElementType.ELEMENT_TYPE_CHAR:
                typeCode = TypeCode.Char; break;

            case CorElementType.ELEMENT_TYPE_I1:
                typeCode = TypeCode.SByte; break;

            case CorElementType.ELEMENT_TYPE_U1:
                typeCode = TypeCode.Byte; break;

            case CorElementType.ELEMENT_TYPE_I2:
                typeCode = TypeCode.Int16; break;

            case CorElementType.ELEMENT_TYPE_U2:
                typeCode = TypeCode.UInt16; break;

            case CorElementType.ELEMENT_TYPE_I4:
                typeCode = TypeCode.Int32; break;

            case CorElementType.ELEMENT_TYPE_U4:
                typeCode = TypeCode.UInt32; break;

            case CorElementType.ELEMENT_TYPE_I8:
                typeCode = TypeCode.Int64; break;

            case CorElementType.ELEMENT_TYPE_U8:
                typeCode = TypeCode.UInt64; break;

            case CorElementType.ELEMENT_TYPE_R4:
                typeCode = TypeCode.Single; break;

            case CorElementType.ELEMENT_TYPE_R8:
                typeCode = TypeCode.Double; break;

#if !CORECLR
            case CorElementType.ELEMENT_TYPE_STRING:
                typeCode = TypeCode.String; break;
#endif
            case CorElementType.ELEMENT_TYPE_VALUETYPE:
                if (ReferenceEquals(this, typeof(decimal)))
                {
                    typeCode = TypeCode.Decimal;
                }
                else if (ReferenceEquals(this, typeof(DateTime)))
                {
                    typeCode = TypeCode.DateTime;
                }
                else if (IsActualEnum)
                {
                    typeCode = GetTypeCode(Enum.InternalGetUnderlyingType(this));
                }
                else
                {
                    typeCode = TypeCode.Object;
                }
                break;

            default:
#if CORECLR
                // GetSignatureCorElementType returns E_T_CLASS for E_T_STRING
                if (ReferenceEquals(this, typeof(string)))
                {
                    typeCode = TypeCode.String;
                    break;
                }
#endif
                if (ReferenceEquals(this, typeof(DBNull)))
                {
                    typeCode = TypeCode.DBNull;
                    break;
                }

                typeCode = TypeCode.Object;
                break;
            }

            Cache.TypeCode = typeCode;

            return(typeCode);
        }
コード例 #6
0
ファイル: RuntimeType.cs プロジェクト: mikem8361/runtime
        /// <summary>
        /// Retrieves an array of the values of the underlying type constants in a specified enumeration type.
        /// </summary>
        /// <remarks>
        /// This method can be used to get enumeration values when creating an array of the enumeration type is challenging.
        /// For example, <see cref="T:System.Reflection.MetadataLoadContext" /> or on a platform where runtime codegen is not available.
        /// </remarks>
        /// <returns>An array that contains the values of the underlying type constants in enumType.</returns>
        /// <exception cref="ArgumentException">
        /// Thrown when the type is not Enum
        /// </exception>
        public override Array GetEnumValuesAsUnderlyingType()
        {
            if (!IsActualEnum)
            {
                throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
            }

            // Get all of the values
            ulong[] values = Enum.InternalGetValues(this);

            switch (RuntimeTypeHandle.GetCorElementType(Enum.InternalGetUnderlyingType(this)))
            {
            case CorElementType.ELEMENT_TYPE_U1:
            {
                var ret = new byte[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    ret[i] = (byte)values[i];
                }
                return(ret);
            }

            case CorElementType.ELEMENT_TYPE_U2:
            {
                var ret = new ushort[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    ret[i] = (ushort)values[i];
                }
                return(ret);
            }

            case CorElementType.ELEMENT_TYPE_U4:
            {
                var ret = new uint[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    ret[i] = (uint)values[i];
                }
                return(ret);
            }

            case CorElementType.ELEMENT_TYPE_U8:
            {
                return((Array)values.Clone());
            }

            case CorElementType.ELEMENT_TYPE_I1:
            {
                var ret = new sbyte[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    ret[i] = (sbyte)values[i];
                }
                return(ret);
            }

            case CorElementType.ELEMENT_TYPE_I2:
            {
                var ret = new short[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    ret[i] = (short)values[i];
                }
                return(ret);
            }

            case CorElementType.ELEMENT_TYPE_I4:
            {
                var ret = new int[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    ret[i] = (int)values[i];
                }
                return(ret);
            }

            case CorElementType.ELEMENT_TYPE_I8:
            {
                var ret = new long[values.Length];
                for (int i = 0; i < values.Length; i++)
                {
                    ret[i] = (long)values[i];
                }
                return(ret);
            }

            default:
                throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
            }
        }