16
16
// to work well for them because the right behavior is often unclear, and it is hard to test and
17
17
// very low value because such enums cannot be expressed in C# and are very rarely encountered.
18
18
19
+ #pragma warning disable 8500 // Allow taking address of managed types
20
+
19
21
namespace System
20
22
{
21
23
/// <summary>Provides the base class for enumerations.</summary>
@@ -34,25 +36,25 @@ public abstract partial class Enum : ValueType, IComparable, ISpanFormattable, I
34
36
/// or <see langword="null"/> if no such constant is found.
35
37
/// </returns>
36
38
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
37
- public static string ? GetName < TEnum > ( TEnum value ) where TEnum : struct , Enum
39
+ public static unsafe string ? GetName < TEnum > ( TEnum value ) where TEnum : struct , Enum
38
40
{
39
41
RuntimeType rt = ( RuntimeType ) typeof ( TEnum ) ;
40
42
Type underlyingType = typeof ( TEnum ) . GetEnumUnderlyingType ( ) ;
41
43
42
- if ( underlyingType == typeof ( int ) ) return GetNameInlined ( GetEnumInfo < int > ( rt ) , Unsafe . As < TEnum , int > ( ref value ) ) ;
43
- if ( underlyingType == typeof ( uint ) ) return GetNameInlined ( GetEnumInfo < uint > ( rt ) , Unsafe . As < TEnum , uint > ( ref value ) ) ;
44
- if ( underlyingType == typeof ( long ) ) return GetNameInlined ( GetEnumInfo < long > ( rt ) , Unsafe . As < TEnum , long > ( ref value ) ) ;
45
- if ( underlyingType == typeof ( ulong ) ) return GetNameInlined ( GetEnumInfo < ulong > ( rt ) , Unsafe . As < TEnum , ulong > ( ref value ) ) ;
46
- if ( underlyingType == typeof ( byte ) ) return GetNameInlined ( GetEnumInfo < byte > ( rt ) , Unsafe . As < TEnum , byte > ( ref value ) ) ;
47
- if ( underlyingType == typeof ( sbyte ) ) return GetNameInlined ( GetEnumInfo < sbyte > ( rt ) , Unsafe . As < TEnum , sbyte > ( ref value ) ) ;
48
- if ( underlyingType == typeof ( short ) ) return GetNameInlined ( GetEnumInfo < short > ( rt ) , Unsafe . As < TEnum , short > ( ref value ) ) ;
49
- if ( underlyingType == typeof ( ushort ) ) return GetNameInlined ( GetEnumInfo < ushort > ( rt ) , Unsafe . As < TEnum , ushort > ( ref value ) ) ;
50
- if ( underlyingType == typeof ( nint ) ) return GetNameInlined ( GetEnumInfo < nint > ( rt ) , Unsafe . As < TEnum , nint > ( ref value ) ) ;
51
- if ( underlyingType == typeof ( nuint ) ) return GetNameInlined ( GetEnumInfo < nuint > ( rt ) , Unsafe . As < TEnum , nuint > ( ref value ) ) ;
52
- if ( underlyingType == typeof ( char ) ) return GetNameInlined ( GetEnumInfo < char > ( rt ) , Unsafe . As < TEnum , char > ( ref value ) ) ;
53
- if ( underlyingType == typeof ( float ) ) return GetNameInlined ( GetEnumInfo < float > ( rt ) , Unsafe . As < TEnum , float > ( ref value ) ) ;
54
- if ( underlyingType == typeof ( double ) ) return GetNameInlined ( GetEnumInfo < double > ( rt ) , Unsafe . As < TEnum , double > ( ref value ) ) ;
55
- if ( underlyingType == typeof ( bool ) ) return GetNameInlined ( GetEnumInfo < byte > ( rt ) , Unsafe . As < TEnum , bool > ( ref value ) ? ( byte ) 1 : ( byte ) 0 ) ;
44
+ if ( underlyingType == typeof ( int ) ) return GetNameInlined ( GetEnumInfo < int > ( rt ) , * ( int * ) & value ) ;
45
+ if ( underlyingType == typeof ( uint ) ) return GetNameInlined( GetEnumInfo < uint > ( rt ) , * ( uint * ) & value ) ;
46
+ if ( underlyingType == typeof ( long ) ) return GetNameInlined( GetEnumInfo < long > ( rt ) , * ( long * ) & value ) ;
47
+ if ( underlyingType == typeof ( ulong ) ) return GetNameInlined( GetEnumInfo < ulong > ( rt ) , * ( ulong * ) & value ) ;
48
+ if ( underlyingType == typeof ( byte ) ) return GetNameInlined( GetEnumInfo < byte > ( rt ) , * ( byte * ) & value ) ;
49
+ if ( underlyingType == typeof ( sbyte ) ) return GetNameInlined( GetEnumInfo < sbyte > ( rt ) , * ( sbyte * ) & value ) ;
50
+ if ( underlyingType == typeof ( short ) ) return GetNameInlined( GetEnumInfo < short > ( rt ) , * ( short * ) & value ) ;
51
+ if ( underlyingType == typeof ( ushort ) ) return GetNameInlined( GetEnumInfo < ushort > ( rt ) , * ( ushort * ) & value ) ;
52
+ if ( underlyingType == typeof ( nint ) ) return GetNameInlined( GetEnumInfo < nint > ( rt ) , * ( nint * ) & value ) ;
53
+ if ( underlyingType == typeof ( nuint ) ) return GetNameInlined( GetEnumInfo < nuint > ( rt ) , * ( nuint * ) & value ) ;
54
+ if ( underlyingType == typeof ( char ) ) return GetNameInlined( GetEnumInfo < char > ( rt ) , * ( char * ) & value ) ;
55
+ if ( underlyingType == typeof ( float ) ) return GetNameInlined( GetEnumInfo < float > ( rt ) , * ( float * ) & value ) ;
56
+ if ( underlyingType == typeof ( double ) ) return GetNameInlined( GetEnumInfo < double > ( rt ) , * ( double * ) & value ) ;
57
+ if ( underlyingType == typeof ( bool ) ) return GetNameInlined( GetEnumInfo < byte > ( rt ) , * ( bool * ) & value ? ( byte ) 1 : ( byte ) 0 ) ;
56
58
57
59
throw CreateUnknownEnumTypeException ( ) ;
58
60
}
@@ -506,25 +508,25 @@ private static bool[] CopyByteArrayToNewBoolArray(byte[] bytes)
506
508
/// <param name="value">The value or name of a constant in <typeparamref name="TEnum"/>.</param>
507
509
/// <returns><see langword="true"/> if a given integral value exists in a specified enumeration; <see langword="false"/>, otherwise.</returns>
508
510
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
509
- public static bool IsDefined < TEnum > ( TEnum value ) where TEnum : struct , Enum
511
+ public static unsafe bool IsDefined< TEnum > ( TEnum value ) where TEnum : struct , Enum
510
512
{
511
513
RuntimeType rt = ( RuntimeType ) typeof( TEnum ) ;
512
514
Type underlyingType = typeof ( TEnum ) . GetEnumUnderlyingType ( ) ;
513
515
514
- if ( underlyingType == typeof ( int ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , int > ( ref value ) ) ;
515
- if ( underlyingType == typeof ( uint ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , uint > ( ref value ) ) ;
516
- if ( underlyingType == typeof ( long ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , long > ( ref value ) ) ;
517
- if ( underlyingType == typeof ( ulong ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , ulong > ( ref value ) ) ;
518
- if ( underlyingType == typeof ( byte ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , byte > ( ref value ) ) ;
519
- if ( underlyingType == typeof ( sbyte ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , sbyte > ( ref value ) ) ;
520
- if ( underlyingType == typeof ( short ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , short > ( ref value ) ) ;
521
- if ( underlyingType == typeof ( ushort ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , ushort > ( ref value ) ) ;
522
- if ( underlyingType == typeof ( nint ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , nint > ( ref value ) ) ;
523
- if ( underlyingType == typeof ( nuint ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , nuint > ( ref value ) ) ;
524
- if ( underlyingType == typeof ( char ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , char > ( ref value ) ) ;
525
- if ( underlyingType == typeof ( float ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , float > ( ref value ) ) ;
526
- if ( underlyingType == typeof ( double ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , double > ( ref value ) ) ;
527
- if ( underlyingType == typeof ( bool ) ) return IsDefinedPrimitive ( rt , Unsafe . As < TEnum , bool > ( ref value ) ? ( byte ) 1 : ( byte ) 0 ) ;
516
+ if ( underlyingType = = typeof ( int ) ) return IsDefinedPrimitive ( rt , * ( int * ) & value ) ;
517
+ if ( underlyingType = = typeof ( uint ) ) return IsDefinedPrimitive ( rt , * ( uint * ) & value ) ;
518
+ if ( underlyingType = = typeof ( long ) ) return IsDefinedPrimitive ( rt , * ( long * ) & value ) ;
519
+ if ( underlyingType = = typeof ( ulong ) ) return IsDefinedPrimitive ( rt , * ( ulong * ) & value ) ;
520
+ if ( underlyingType = = typeof ( byte ) ) return IsDefinedPrimitive ( rt , * ( byte * ) & value ) ;
521
+ if ( underlyingType = = typeof ( sbyte ) ) return IsDefinedPrimitive ( rt , * ( sbyte * ) & value ) ;
522
+ if ( underlyingType = = typeof ( short ) ) return IsDefinedPrimitive ( rt , * ( short * ) & value ) ;
523
+ if ( underlyingType = = typeof ( ushort ) ) return IsDefinedPrimitive ( rt , * ( ushort * ) & value ) ;
524
+ if ( underlyingType = = typeof ( nint ) ) return IsDefinedPrimitive ( rt , * ( nint * ) & value ) ;
525
+ if ( underlyingType = = typeof ( nuint ) ) return IsDefinedPrimitive ( rt , * ( nuint * ) & value ) ;
526
+ if ( underlyingType = = typeof ( char ) ) return IsDefinedPrimitive ( rt , * ( char * ) & value ) ;
527
+ if ( underlyingType = = typeof ( float ) ) return IsDefinedPrimitive ( rt , * ( float * ) & value ) ;
528
+ if ( underlyingType = = typeof ( double ) ) return IsDefinedPrimitive ( rt , * ( double * ) & value ) ;
529
+ if ( underlyingType = = typeof ( bool ) ) return IsDefinedPrimitive ( rt , * ( bool * ) & value ? ( byte ) 1 : ( byte ) 0 ) ;
528
530
529
531
throw CreateUnknownEnumTypeException( ) ;
530
532
}
@@ -1877,7 +1879,7 @@ public static unsafe bool TryFormat<TEnum>(TEnum value, Span<char> destination,
1877
1879
/// those constraints. It's a manual copy/paste right now to avoid pressure on the JIT's inlining mechanisms.
1878
1880
/// </remarks>
1879
1881
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ] // format is most frequently a constant, and we want it exposed to the implementation; this should be inlined automatically, anyway
1880
- internal static bool TryFormatUnconstrained< TEnum> ( TEnum value , Span < char > destination , out int charsWritten, [ StringSyntax ( StringSyntaxAttribute . EnumFormat ) ] ReadOnlySpan < char > format = default )
1882
+ internal static unsafe bool TryFormatUnconstrained< TEnum> ( TEnum value , Span < char > destination , out int charsWritten, [ StringSyntax ( StringSyntaxAttribute . EnumFormat ) ] ReadOnlySpan < char > format = default )
1881
1883
{
1882
1884
Debug . Assert ( typeof ( TEnum ) . IsEnum) ;
1883
1885
Debug . Assert ( value is not null ) ;
@@ -1891,37 +1893,37 @@ internal static bool TryFormatUnconstrained<TEnum>(TEnum value, Span<char> desti
1891
1893
// be necessary for semantics inside of TryFormatPrimitiveNonDefault, so we can just do it here instead.
1892
1894
if ( format . IsEmpty )
1893
1895
{
1894
- if ( underlyingType = = typeof ( int ) ) return TryFormatPrimitiveDefault ( rt , Unsafe . As < TEnum , int > ( ref value ) , destination , out charsWritten ) ;
1895
- if ( underlyingType = = typeof ( uint ) ) return TryFormatPrimitiveDefault ( rt , Unsafe . As < TEnum , uint > ( ref value ) , destination , out charsWritten ) ;
1896
- if ( underlyingType == typeof ( long ) ) return TryFormatPrimitiveDefault ( rt , Unsafe . As < TEnum , long > ( ref value ) , destination , out charsWritten ) ;
1897
- if ( underlyingType == typeof ( ulong ) ) return TryFormatPrimitiveDefault ( rt , Unsafe . As < TEnum , ulong > ( ref value ) , destination , out charsWritten ) ;
1898
- if ( underlyingType == typeof ( byte ) ) return TryFormatPrimitiveDefault( rt, Unsafe . As < TEnum , byte > ( ref value ) , destination , out charsWritten ) ;
1899
- if ( underlyingType == typeof ( sbyte ) ) return TryFormatPrimitiveDefault( rt, Unsafe . As < TEnum , sbyte > ( ref value ) , destination , out charsWritten ) ;
1900
- if ( underlyingType == typeof ( short ) ) return TryFormatPrimitiveDefault( rt, Unsafe . As < TEnum , short > ( ref value ) , destination , out charsWritten ) ;
1901
- if ( underlyingType == typeof ( ushort ) ) return TryFormatPrimitiveDefault( rt, Unsafe . As < TEnum , ushort > ( ref value ) , destination , out charsWritten ) ;
1902
- if ( underlyingType == typeof ( nint ) ) return TryFormatPrimitiveDefault( rt, Unsafe . As < TEnum , nint > ( ref value ) , destination , out charsWritten ) ;
1903
- if ( underlyingType == typeof ( nuint ) ) return TryFormatPrimitiveDefault( rt, Unsafe . As < TEnum , nuint > ( ref value ) , destination , out charsWritten ) ;
1904
- if ( underlyingType == typeof ( char ) ) return TryFormatPrimitiveDefault( rt, Unsafe . As < TEnum , char > ( ref value ) , destination , out charsWritten ) ;
1905
- if ( underlyingType = = typeof ( float ) ) return TryFormatPrimitiveDefault ( rt , Unsafe . As < TEnum , float > ( ref value ) , destination , out charsWritten ) ;
1906
- if ( underlyingType == typeof ( double ) ) return TryFormatPrimitiveDefault( rt, Unsafe . As < TEnum , double > ( ref value ) , destination , out charsWritten ) ;
1907
- if ( underlyingType == typeof ( bool ) ) return TryFormatBool( rt, Unsafe . As < TEnum , bool > ( ref value ) , destination , out charsWritten , format : default ) ;
1896
+ if ( underlyingType = = typeof ( int ) ) return TryFormatPrimitiveDefault ( rt , * ( int * ) & value , destination , out charsWritten ) ;
1897
+ if ( underlyingType = = typeof ( uint ) ) return TryFormatPrimitiveDefault ( rt , * ( uint * ) & value , destination , out charsWritten ) ;
1898
+ if ( underlyingType = = typeof ( long ) ) return TryFormatPrimitiveDefault ( rt , * ( long * ) & value , destination , out charsWritten ) ;
1899
+ if ( underlyingType = = typeof ( ulong ) ) return TryFormatPrimitiveDefault ( rt , * ( ulong * ) & value , destination , out charsWritten ) ;
1900
+ if ( underlyingType = = typeof ( byte ) ) return TryFormatPrimitiveDefault ( rt , * ( byte * ) & value , destination , out charsWritten ) ;
1901
+ if ( underlyingType = = typeof ( sbyte ) ) return TryFormatPrimitiveDefault ( rt , * ( sbyte * ) & value , destination , out charsWritten ) ;
1902
+ if ( underlyingType = = typeof ( short ) ) return TryFormatPrimitiveDefault ( rt , * ( short * ) & value , destination , out charsWritten ) ;
1903
+ if ( underlyingType = = typeof ( ushort ) ) return TryFormatPrimitiveDefault ( rt , * ( ushort * ) & value , destination , out charsWritten ) ;
1904
+ if ( underlyingType = = typeof ( nint ) ) return TryFormatPrimitiveDefault ( rt , * ( nint * ) & value , destination , out charsWritten ) ;
1905
+ if ( underlyingType = = typeof ( nuint ) ) return TryFormatPrimitiveDefault ( rt , * ( nuint * ) & value , destination , out charsWritten ) ;
1906
+ if ( underlyingType = = typeof ( char ) ) return TryFormatPrimitiveDefault ( rt , * ( char * ) & value , destination , out charsWritten ) ;
1907
+ if ( underlyingType = = typeof ( float ) ) return TryFormatPrimitiveDefault ( rt , * ( float * ) & value , destination , out charsWritten ) ;
1908
+ if ( underlyingType = = typeof ( double ) ) return TryFormatPrimitiveDefault ( rt , * ( double * ) & value , destination , out charsWritten ) ;
1909
+ if ( underlyingType = = typeof ( bool ) ) return TryFormatBool ( rt , * ( bool * ) & value , destination , out charsWritten , format : default ) ;
1908
1910
}
1909
1911
else
1910
1912
{
1911
- if ( underlyingType == typeof ( int ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , int > ( ref value ) , destination, out charsWritten, format) ;
1912
- if ( underlyingType == typeof ( uint ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , uint > ( ref value ) , destination, out charsWritten, format) ;
1913
- if ( underlyingType == typeof ( long ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , long > ( ref value ) , destination, out charsWritten, format) ;
1914
- if ( underlyingType == typeof ( ulong ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , ulong > ( ref value ) , destination, out charsWritten, format) ;
1915
- if ( underlyingType == typeof ( byte ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , byte > ( ref value ) , destination, out charsWritten, format) ;
1916
- if ( underlyingType == typeof ( sbyte ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , sbyte > ( ref value ) , destination, out charsWritten, format) ;
1917
- if ( underlyingType == typeof ( short ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , short > ( ref value ) , destination, out charsWritten, format) ;
1918
- if ( underlyingType == typeof ( ushort ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , ushort > ( ref value ) , destination, out charsWritten, format) ;
1919
- if ( underlyingType == typeof ( nint ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , nint > ( ref value ) , destination, out charsWritten, format) ;
1920
- if ( underlyingType == typeof ( nuint ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , nuint > ( ref value ) , destination, out charsWritten, format) ;
1921
- if ( underlyingType == typeof ( char ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , char > ( ref value ) , destination, out charsWritten, format) ;
1922
- if ( underlyingType == typeof ( float ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , float > ( ref value ) , destination, out charsWritten, format) ;
1923
- if ( underlyingType == typeof ( double ) ) return TryFormatPrimitiveNonDefault( rt, Unsafe . As < TEnum , double > ( ref value ) , destination, out charsWritten, format) ;
1924
- if ( underlyingType == typeof ( bool ) ) return TryFormatBool( rt, Unsafe . As < TEnum , bool > ( ref value ) , destination, out charsWritten, format) ;
1913
+ if ( underlyingType = = typeof ( int ) ) return TryFormatPrimitiveNonDefault ( rt , * ( int * ) & value , destination , out charsWritten , format ) ;
1914
+ if ( underlyingType = = typeof ( uint ) ) return TryFormatPrimitiveNonDefault ( rt , * ( uint * ) & value , destination , out charsWritten , format ) ;
1915
+ if ( underlyingType = = typeof ( long ) ) return TryFormatPrimitiveNonDefault ( rt , * ( long * ) & value , destination , out charsWritten , format ) ;
1916
+ if ( underlyingType = = typeof ( ulong ) ) return TryFormatPrimitiveNonDefault ( rt , * ( ulong * ) & value , destination , out charsWritten , format ) ;
1917
+ if ( underlyingType = = typeof ( byte ) ) return TryFormatPrimitiveNonDefault ( rt , * ( byte * ) & value , destination , out charsWritten , format ) ;
1918
+ if ( underlyingType = = typeof ( sbyte ) ) return TryFormatPrimitiveNonDefault ( rt , * ( sbyte * ) & value , destination , out charsWritten , format ) ;
1919
+ if ( underlyingType = = typeof ( short ) ) return TryFormatPrimitiveNonDefault ( rt , * ( short * ) & value , destination , out charsWritten , format ) ;
1920
+ if ( underlyingType = = typeof ( ushort ) ) return TryFormatPrimitiveNonDefault ( rt , * ( ushort * ) & value , destination , out charsWritten , format ) ;
1921
+ if ( underlyingType = = typeof ( nint ) ) return TryFormatPrimitiveNonDefault ( rt , * ( nint * ) & value , destination , out charsWritten , format ) ;
1922
+ if ( underlyingType = = typeof ( nuint ) ) return TryFormatPrimitiveNonDefault ( rt , * ( nuint * ) & value , destination , out charsWritten , format ) ;
1923
+ if ( underlyingType = = typeof ( char ) ) return TryFormatPrimitiveNonDefault ( rt , * ( char * ) & value , destination , out charsWritten , format ) ;
1924
+ if ( underlyingType = = typeof ( float ) ) return TryFormatPrimitiveNonDefault ( rt , * ( float * ) & value , destination , out charsWritten , format ) ;
1925
+ if ( underlyingType = = typeof ( double ) ) return TryFormatPrimitiveNonDefault ( rt , * ( double * ) & value , destination , out charsWritten , format ) ;
1926
+ if ( underlyingType = = typeof ( bool ) ) return TryFormatBool ( rt , * ( bool * ) & value , destination , out charsWritten , format ) ;
1925
1927
}
1926
1928
1927
1929
throw CreateUnknownEnumTypeException ( ) ;
0 commit comments