@@ -61,39 +61,74 @@ public int Compare(ReadOnlyMemory<char> x, ReadOnlyMemory<char> y)
6161 }
6262
6363 public static int Compare ( ReadOnlySpan < char > x , ReadOnlySpan < char > y , StringComparison stringComparison )
64- {
65- var length = Math . Min ( x . Length , y . Length ) ;
64+ {
65+ // Handle file extensions specially
66+ int xExtPos = GetExtensionPosition ( x ) ;
67+ int yExtPos = GetExtensionPosition ( y ) ;
68+
69+ // If both have extensions, compare the names first
70+ if ( xExtPos >= 0 && yExtPos >= 0 )
71+ {
72+ var xName = x . Slice ( 0 , xExtPos ) ;
73+ var yName = y . Slice ( 0 , yExtPos ) ;
74+
75+ int nameCompare = CompareWithoutExtension ( xName , yName , stringComparison ) ;
76+ if ( nameCompare != 0 )
77+ return nameCompare ;
78+
79+ // If names match, compare extensions
80+ return x . Slice ( xExtPos ) . CompareTo ( y . Slice ( yExtPos ) , stringComparison ) ;
81+ }
82+
83+ // Original comparison logic for non-extension cases
84+ return CompareWithoutExtension ( x , y , stringComparison ) ;
85+ }
6686
67- for ( var i = 0 ; i < length ; i ++ )
68- {
87+ private static int CompareWithoutExtension ( ReadOnlySpan < char > x , ReadOnlySpan < char > y , StringComparison stringComparison )
88+ {
89+ var length = Math . Min ( x . Length , y . Length ) ;
90+
91+ for ( var i = 0 ; i < length ; i ++ )
92+ {
6993 while ( i < x . Length && i < y . Length && IsIgnorableSeparator ( x , i ) && IsIgnorableSeparator ( y , i ) )
70- i ++ ;
94+ i ++ ;
7195
72- if ( i >= x . Length || i >= y . Length ) break ;
96+ if ( i >= x . Length || i >= y . Length ) break ;
7397
74- if ( char . IsDigit ( x [ i ] ) && char . IsDigit ( y [ i ] ) )
75- {
76- var xOut = GetNumber ( x . Slice ( i ) , out var xNumAsSpan ) ;
77- var yOut = GetNumber ( y . Slice ( i ) , out var yNumAsSpan ) ;
98+ if ( char . IsDigit ( x [ i ] ) && char . IsDigit ( y [ i ] ) )
99+ {
100+ var xOut = GetNumber ( x . Slice ( i ) , out var xNumAsSpan ) ;
101+ var yOut = GetNumber ( y . Slice ( i ) , out var yNumAsSpan ) ;
78102
79- var compareResult = CompareNumValues ( xNumAsSpan , yNumAsSpan ) ;
103+ var compareResult = CompareNumValues ( xNumAsSpan , yNumAsSpan ) ;
80104
81- if ( compareResult != 0 ) return compareResult ;
105+ if ( compareResult != 0 ) return compareResult ;
82106
83- i = - 1 ;
84- length = Math . Min ( xOut . Length , yOut . Length ) ;
107+ i = - 1 ;
108+ length = Math . Min ( xOut . Length , yOut . Length ) ;
85109
86- x = xOut ;
87- y = yOut ;
88- continue ;
89- }
110+ x = xOut ;
111+ y = yOut ;
112+ continue ;
113+ }
90114
91- var charCompareResult = x . Slice ( i , 1 ) . CompareTo ( y . Slice ( i , 1 ) , stringComparison ) ;
92- if ( charCompareResult != 0 ) return charCompareResult ;
93- }
115+ var charCompareResult = x . Slice ( i , 1 ) . CompareTo ( y . Slice ( i , 1 ) , stringComparison ) ;
116+ if ( charCompareResult != 0 ) return charCompareResult ;
117+ }
94118
95- return x . Length . CompareTo ( y . Length ) ;
96- }
119+ return x . Length . CompareTo ( y . Length ) ;
120+ }
121+
122+ private static int GetExtensionPosition ( ReadOnlySpan < char > text )
123+ {
124+ // Find the last period that's not at the beginning
125+ for ( int i = text . Length - 1 ; i > 0 ; i -- )
126+ {
127+ if ( text [ i ] == '.' )
128+ return i ;
129+ }
130+ return - 1 ;
131+ }
97132
98133 private static bool IsIgnorableSeparator ( ReadOnlySpan < char > span , int index )
99134 {
0 commit comments