@@ -140,14 +140,27 @@ public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(this I
140
140
141
141
/// <summary>Gets whether the results of an unstable sort will be observably the same as a stable sort.</summary>
142
142
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
143
- internal static bool TypeIsImplicitlyStable < T > ( ) =>
144
- typeof ( T ) == typeof ( sbyte ) || typeof ( T ) == typeof ( byte ) ||
145
- typeof ( T ) == typeof ( int ) || typeof ( T ) == typeof ( uint ) ||
146
- typeof ( T ) == typeof ( short ) || typeof ( T ) == typeof ( ushort ) ||
147
- typeof ( T ) == typeof ( long ) || typeof ( T ) == typeof ( ulong ) ||
148
- typeof ( T ) == typeof ( Int128 ) || typeof ( T ) == typeof ( UInt128 ) ||
149
- typeof ( T ) == typeof ( nint ) || typeof ( T ) == typeof ( nuint ) ||
150
- typeof ( T ) == typeof ( bool ) || typeof ( T ) == typeof ( char ) ;
143
+ internal static bool TypeIsImplicitlyStable < T > ( )
144
+ {
145
+ Type t = typeof ( T ) ;
146
+ if ( typeof ( T ) . IsEnum )
147
+ {
148
+ t = typeof ( T ) . GetEnumUnderlyingType ( ) ;
149
+ }
150
+
151
+ // Check for integral primitive types that compare equally iff they have the same bit pattern.
152
+ // bool is included because, even though technically it can have 256 different values, anything
153
+ // other than 0/1 is only producible using unsafe code. It's tempting to include a type like string
154
+ // here, as it's so commonly used with ordering, but two different string objects can compare equally,
155
+ // and their reference identity can be observable in a stable vs unstable sort.
156
+ return
157
+ t == typeof ( sbyte ) || t == typeof ( byte ) || t == typeof ( bool ) ||
158
+ t == typeof ( short ) || t == typeof ( ushort ) || t == typeof ( char ) ||
159
+ t == typeof ( int ) || t == typeof ( uint ) ||
160
+ t == typeof ( long ) || t == typeof ( ulong ) ||
161
+ t == typeof ( Int128 ) || t == typeof ( UInt128 ) ||
162
+ t == typeof ( nint ) || t == typeof ( nuint ) ;
163
+ }
151
164
}
152
165
153
166
public interface IOrderedEnumerable < out TElement > : IEnumerable < TElement >
0 commit comments