diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs index cce84ae6ed1f8..719424c6faefd 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs @@ -111,6 +111,14 @@ public sealed override Array GetEnumValues() return result; } + public sealed override Array GetEnumValuesAsUnderlyingType() + { + if (!IsActualEnum) + throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); + + return (Array)Enum.GetEnumInfo(this).ValuesAsUnderlyingType.Clone(); + } + internal bool IsActualEnum => TryGetEEType(out EETypePtr eeType) && eeType.IsEnum; } diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs index 81e10e504d83e..5dcc263e0d0c0 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System/ComponentModel/EnumConverter.cs @@ -62,7 +62,7 @@ public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen( /// protected virtual IComparer Comparer => InvariantComparer.Default; - private static long GetEnumValue(bool isUnderlyingTypeUInt64, Enum enumVal, CultureInfo? culture) + private static long GetEnumValue(bool isUnderlyingTypeUInt64, object enumVal, CultureInfo? culture) { return isUnderlyingTypeUInt64 ? unchecked((long)Convert.ToUInt64(enumVal, culture)) : @@ -85,7 +85,7 @@ private static long GetEnumValue(bool isUnderlyingTypeUInt64, Enum enumVal, Cult string[] values = strValue.Split(','); foreach (string v in values) { - convertedValue |= GetEnumValue(isUnderlyingTypeUInt64, (Enum)Enum.Parse(EnumType, v, true), culture); + convertedValue |= GetEnumValue(isUnderlyingTypeUInt64, Enum.Parse(EnumType, v, true), culture); } return Enum.ToObject(EnumType, convertedValue); } @@ -171,14 +171,14 @@ private static long GetEnumValue(bool isUnderlyingTypeUInt64, Enum enumVal, Cult bool isUnderlyingTypeUInt64 = Enum.GetUnderlyingType(EnumType) == typeof(ulong); List flagValues = new List(); - Array objValues = Enum.GetValues(EnumType); + Array objValues = Enum.GetValuesAsUnderlyingType(EnumType); long[] ulValues = new long[objValues.Length]; for (int idx = 0; idx < objValues.Length; idx++) { - ulValues[idx] = GetEnumValue(isUnderlyingTypeUInt64, (Enum)objValues.GetValue(idx)!, culture); + ulValues[idx] = GetEnumValue(isUnderlyingTypeUInt64, objValues.GetValue(idx)!, culture); } - long longValue = GetEnumValue(isUnderlyingTypeUInt64, (Enum)value, culture); + long longValue = GetEnumValue(isUnderlyingTypeUInt64, value, culture); bool valueFound = true; while (valueFound) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Enum.cs b/src/libraries/System.Private.CoreLib/src/System/Enum.cs index e3f994148b55d..89404415b5e17 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Enum.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Enum.cs @@ -315,13 +315,46 @@ public static TEnum[] GetValues() where TEnum : struct, Enum => (TEnum[])GetValues(typeof(TEnum)); #endif - [RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use the GetValues overload instead.")] + [RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use the GetValues overload or the GetValuesAsUnderlyingType method instead.")] public static Array GetValues(Type enumType) { ArgumentNullException.ThrowIfNull(enumType); return enumType.GetEnumValues(); } + /// + /// Retrieves an array of the values of the underlying type constants in a specified enumeration type. + /// + /// An enumeration type. + /// /// + /// This method can be used to get enumeration values when creating an array of the enumeration type is challenging. + /// For example, or on a platform where runtime codegen is not available. + /// + /// An array that contains the values of the underlying type constants in enumType. + public static Array GetValuesAsUnderlyingType() where TEnum : struct, Enum => + typeof(TEnum).GetEnumValuesAsUnderlyingType(); + + /// + /// Retrieves an array of the values of the underlying type constants in a specified enumeration. + /// + /// An enumeration type. + /// + /// This method can be used to get enumeration values when creating an array of the enumeration type is challenging. + /// For example, or on a platform where runtime codegen is not available. + /// + /// An array that contains the values of the underlying type constants in . + /// + /// Thrown when the enumeration type is null. + /// + /// + /// Thrown when the type is not an enumeration type. + /// + public static Array GetValuesAsUnderlyingType(Type enumType) + { + ArgumentNullException.ThrowIfNull(enumType); + return enumType.GetEnumValuesAsUnderlyingType(); + } + [Intrinsic] public bool HasFlag(Enum flag) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureType.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureType.cs index 1d7251ed5df2e..56d9d454e9717 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureType.cs @@ -99,7 +99,7 @@ public sealed override Type MakeArrayType(int rank) public sealed override string GetEnumName(object value) => throw new NotSupportedException(SR.NotSupported_SignatureType); public sealed override string[] GetEnumNames() => throw new NotSupportedException(SR.NotSupported_SignatureType); public sealed override Type GetEnumUnderlyingType() => throw new NotSupportedException(SR.NotSupported_SignatureType); - [RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use Enum.GetValues instead.")] + [RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use the GetEnumValues overload or the GetEnumValuesAsUnderlyingType method instead.")] public sealed override Array GetEnumValues() => throw new NotSupportedException(SR.NotSupported_SignatureType); public sealed override Guid GUID => throw new NotSupportedException(SR.NotSupported_SignatureType); protected sealed override TypeCode GetTypeCodeImpl() => throw new NotSupportedException(SR.NotSupported_SignatureType); diff --git a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs index 0182163de6aef..81d6f994da54f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs @@ -118,7 +118,7 @@ public override string[] GetEnumNames() return new ReadOnlySpan(ret).ToArray(); } - [RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use the GetValues overload instead.")] + [RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use the GetEnumValues overload or the GetEnumValuesAsUnderlyingType method instead.")] public override Array GetEnumValues() { if (!IsActualEnum) @@ -139,6 +139,107 @@ public override Array GetEnumValues() return ret; } + /// + /// Retrieves an array of the values of the underlying type constants in a specified enumeration type. + /// + /// + /// This method can be used to get enumeration values when creating an array of the enumeration type is challenging. + /// For example, or on a platform where runtime codegen is not available. + /// + /// An array that contains the values of the underlying type constants in enumType. + /// + /// Thrown when the type is not Enum + /// + 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); + } + } + public override Type GetEnumUnderlyingType() { if (!IsActualEnum) diff --git a/src/libraries/System.Private.CoreLib/src/System/Type.cs b/src/libraries/System.Private.CoreLib/src/System/Type.cs index 4907875d591c5..e7a64d26f6827 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Type.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Type.cs @@ -515,7 +515,7 @@ public virtual Type GetEnumUnderlyingType() return fields[0].FieldType; } - [RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use Enum.GetValues instead.")] + [RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use the GetEnumValues overload or the GetEnumValuesAsUnderlyingType method instead.")] public virtual Array GetEnumValues() { if (!IsEnum) @@ -526,6 +526,19 @@ public virtual Array GetEnumValues() throw NotImplemented.ByDesign; } + /// + /// Retrieves an array of the values of the underlying type constants in a specified enumeration type. + /// + /// + /// This method can be used to get enumeration values when creating an array of the enumeration type is challenging. + /// For example, or on a platform where runtime codegen is not available. + /// + /// An array that contains the values of the underlying type constants in enumType. + /// + /// Thrown when the type is not an enumeration type. + /// + public virtual Array GetEnumValuesAsUnderlyingType() => throw new NotSupportedException(SR.NotSupported_SubclassOverride); + [RequiresDynamicCode("The code for an array of the specified type might not be available.")] public virtual Type MakeArrayType() => throw new NotSupportedException(); [RequiresDynamicCode("The code for an array of the specified type might not be available.")] diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs index 57341e16a36d3..e57cafb5ba872 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs @@ -288,6 +288,38 @@ public sealed override Type MakeArrayType(int rank) private volatile RoType? _lazyUnderlyingEnumType; public sealed override Array GetEnumValues() => throw new InvalidOperationException(SR.Arg_InvalidOperation_Reflection); +#if NET7_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2085:UnrecognizedReflectionPattern", + Justification = "Enum Types are not trimmed.")] + public override Array GetEnumValuesAsUnderlyingType() + { + if (!IsEnum) + throw new ArgumentException(SR.Arg_MustBeEnum, "enumType"); + + FieldInfo[] enumFields = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + int numValues = enumFields.Length; + Array ret = Type.GetTypeCode(GetEnumUnderlyingType()) switch + { + TypeCode.Byte => new byte[numValues], + TypeCode.SByte => new sbyte[numValues], + TypeCode.UInt16 => new ushort[numValues], + TypeCode.Int16 => new short[numValues], + TypeCode.UInt32 => new uint[numValues], + TypeCode.Int32 => new int[numValues], + TypeCode.UInt64 => new ulong[numValues], + TypeCode.Int64 => new long[numValues], + _ => throw new NotSupportedException(), + }; + + for (int i = 0; i < numValues; i++) + { + ret.SetValue(enumFields[i].GetRawConstantValue(), i); + } + + return ret; + } +#endif + // No trust environment to apply these to. public sealed override bool IsSecurityCritical => throw new InvalidOperationException(SR.InvalidOperation_IsSecurity); public sealed override bool IsSecuritySafeCritical => throw new InvalidOperationException(SR.InvalidOperation_IsSecurity); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs index b60f7cd86d897..9f01b3b5efcb2 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/SampleMetadata/SampleMetadata.cs @@ -84,6 +84,9 @@ public enum EI4 : int { } public enum EU8 : ulong { } public enum EI8 : long { } + public enum E_2_I4 : int { min=int.MinValue, zero=0, one=1, max=int.MaxValue} + public enum E_2_U4 : uint { min = uint.MinValue, zero = 0, one = 1, max = uint.MaxValue } + public class GenericEnumContainer { public enum GenericEnum : short { } diff --git a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs index c0292e2999957..03611db20825a 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/tests/src/Tests/Type/TypeTests.cs @@ -365,6 +365,30 @@ public static IEnumerable GetEnumUnderlyingTypeData } } +#if NET7_0_OR_GREATER + [Fact] + public static void GetEnumValuesAsUnderlyingType() + { + var intEnumType = typeof(E_2_I4).Project(); + int[] expectedIntValues = { int.MinValue, 0, 1, int.MaxValue }; + Array intArr = intEnumType.GetEnumValuesAsUnderlyingType(); + for (int i = 0; i < intArr.Length; i++) + { + Assert.Equal(expectedIntValues[i], intArr.GetValue(i)); + Assert.Equal(Type.GetTypeCode(expectedIntValues[i].GetType()), Type.GetTypeCode(intArr.GetValue(i).GetType())); + } + + var uintEnumType = typeof(E_2_U4).Project(); + uint[] expectesUIntValues = { uint.MinValue, 0, 1, uint.MaxValue }; + Array uintArr = uintEnumType.GetEnumValuesAsUnderlyingType(); + for (int i = 0; i < uintArr.Length; i++) + { + Assert.Equal(expectesUIntValues[i], uintArr.GetValue(i)); + Assert.Equal(Type.GetTypeCode(expectesUIntValues[i].GetType()), Type.GetTypeCode(uintArr.GetValue(i).GetType())); + } + } +#endif + [Theory] [MemberData(nameof(GetTypeCodeTheoryData))] public static void GettypeCode(TypeWrapper tw, TypeCode expectedTypeCode) diff --git a/src/libraries/System.Reflection/tests/TypeInfoTests.cs b/src/libraries/System.Reflection/tests/TypeInfoTests.cs index 6b553ef4d430b..3e6cd0deeffbc 100644 --- a/src/libraries/System.Reflection/tests/TypeInfoTests.cs +++ b/src/libraries/System.Reflection/tests/TypeInfoTests.cs @@ -457,6 +457,24 @@ private static void GetEnumValues(Type enumType, Array expected) Assert.Equal(expected, enumType.GetTypeInfo().GetEnumValues()); } + [Fact] + public static void GetEnumValuesAsUnderlyingType_Int() + { + GetEnumValuesAsUnderlyingType(typeof(IntEnum), new int[] { 1, 2, 10, 18, 45 }); + } + + [Fact] + public static void GetEnumValuesAsUnderlyingType_UInt() + { + GetEnumValuesAsUnderlyingType(typeof(UIntEnum), new uint[] { 1, 10 }); + } + + private static void GetEnumValuesAsUnderlyingType(Type enumType, Array expected) + { + Assert.Equal(expected, enumType.GetTypeInfo().GetEnumValuesAsUnderlyingType()); + } + + [Fact] public void GetEnumValues_TypeNotEnum_ThrowsArgumentException() { diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 4449a3fd35677..a4f5c4e1e3053 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2312,9 +2312,11 @@ protected Enum() { } public static string[] GetNames() where TEnum: struct, System.Enum { throw null; } public System.TypeCode GetTypeCode() { throw null; } public static System.Type GetUnderlyingType(System.Type enumType) { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use the GetValues overload instead.")] + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use the GetValues overload or the GetValuesAsUnderlyingType method instead.")] public static System.Array GetValues(System.Type enumType) { throw null; } public static TEnum[] GetValues() where TEnum : struct, System.Enum { throw null; } + public static System.Array GetValuesAsUnderlyingType(System.Type enumType) { throw null; } + public static System.Array GetValuesAsUnderlyingType() where TEnum : struct, System.Enum { throw null; } public bool HasFlag(System.Enum flag) { throw null; } public static bool IsDefined(System.Type enumType, object value) { throw null; } public static bool IsDefined(TEnum value) where TEnum : struct, System.Enum { throw null; } @@ -5860,8 +5862,9 @@ protected Type() { } public virtual string? GetEnumName(object value) { throw null; } public virtual string[] GetEnumNames() { throw null; } public virtual System.Type GetEnumUnderlyingType() { throw null; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use Enum.GetValues instead.")] + [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("It might not be possible to create an array of the enum type at runtime. Use the GetEnumValues overload or the GetEnumValuesAsUnderlyingType method instead.")] public virtual System.Array GetEnumValues() { throw null; } + public virtual System.Array GetEnumValuesAsUnderlyingType() { throw null; } [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public System.Reflection.EventInfo? GetEvent(string name) { throw null; } [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicEvents | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] diff --git a/src/libraries/System.Runtime/tests/System/EnumTests.cs b/src/libraries/System.Runtime/tests/System/EnumTests.cs index 245840ee34879..a243e6c7c8bff 100644 --- a/src/libraries/System.Runtime/tests/System/EnumTests.cs +++ b/src/libraries/System.Runtime/tests/System/EnumTests.cs @@ -1589,6 +1589,76 @@ public static void GetValues_NullEnumType_ThrowsArgumentNullException() AssertExtensions.Throws("enumType", () => Enum.GetValues(null)); } + [Fact] + public void GetValuesAsUnderlyingType_InvokeSByteEnum_ReturnsExpected() + { + Array expected = new sbyte[] { 1, 2, sbyte.MaxValue, sbyte.MinValue }; + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType(typeof(SByteEnum))); + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType()); + } + + [Fact] + public void GetValuesAsUnderlyingType_InvokeByteEnum_ReturnsExpected() + { + Array expected = new byte[] { byte.MinValue, 1, 2, byte.MaxValue }; + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType(typeof(ByteEnum))); + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType()); + } + + [Fact] + public void GetValuesAsUnderlyingType_InvokeInt16Enum_ReturnsExpected() + { + Array expected = new short[] { 1, 2, short.MaxValue, short.MinValue }; + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType(typeof(Int16Enum))); + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType()); + } + + [Fact] + public void GetValuesAsUnderlyingType_InvokeUInt16Enum_ReturnsExpected() + { + Array expected = new ushort[] { ushort.MinValue, 1, 2, ushort.MaxValue }; + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType(typeof(UInt16Enum))); + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType()); + } + + [Fact] + public void GetValuesAsUnderlyingType_InvokeInt32Enum_ReturnsExpected() + { + Array expected = new int[] { 1, 2, int.MaxValue, int.MinValue }; + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType(typeof(Int32Enum))); + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType()); + } + + [Fact] + public void GetValuesAsUnderlyingType_InvokeUInt32Enum_ReturnsExpected() + { + Array expected = new uint[] { uint.MinValue, 1, 2, uint.MaxValue }; + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType(typeof(UInt32Enum))); + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType()); + } + + [Fact] + public void GetValuesAsUnderlyingType_InvokeInt64Enum_ReturnsExpected() + { + Array expected = new long[] { 1, 2, long.MaxValue, long.MinValue }; + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType(typeof(Int64Enum))); + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType()); + } + + [Fact] + public void GetValuesAsUnderlyingType_InvokeUInt64Enum_ReturnsExpected() + { + Array expected = new ulong[] { ulong.MinValue, 1, 2, ulong.MaxValue }; + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType(typeof(UInt64Enum))); + Assert.Equal(expected, Enum.GetValuesAsUnderlyingType()); + } + + [Fact] + public static void GetValuesAsUnderlyingType_NullEnumType_ThrowsArgumentNullException() + { + AssertExtensions.Throws("enumType", () => Enum.GetValuesAsUnderlyingType(null)); + } + [Theory] [InlineData(typeof(object))] [InlineData(typeof(int))] diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index 8dc2c6e88a768..676f4e457ed42 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -1434,6 +1434,12 @@ public static void Run() throw new Exception("GetValues"); } + Console.WriteLine("Enum.GetValuesAsUnderlyingType"); + { + if (Enum.GetValuesAsUnderlyingType(typeof(Mine)).GetType() != typeof(int[])) + throw new Exception("Enum.GetValuesAsUnderlyingType"); + } + Console.WriteLine("Pattern in LINQ expressions"); { Type objType = typeof(object);