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); }
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); } }
public override Type GetEnumUnderlyingType() { if (!IsActualEnum) { throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); } return(Enum.InternalGetUnderlyingType(this)); }
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); } }
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); }
/// <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); } }