66using System . Collections . Generic ;
77using System . Globalization ;
88using System . Diagnostics . Contracts ;
9+ using System . Runtime . Serialization ;
910
1011namespace System
1112{
1213 [ Serializable ]
14+ [ System . Runtime . CompilerServices . TypeForwardedFrom ( "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" ) ]
1315 public abstract class StringComparer : IComparer , IEqualityComparer , IComparer < string > , IEqualityComparer < string >
1416 {
1517 private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer ( CultureInfo . InvariantCulture , false ) ;
1618 private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer ( CultureInfo . InvariantCulture , true ) ;
17- private static readonly OrdinalComparer s_ordinal = new OrdinalComparer ( ) ;
19+ private static readonly OrdinalCaseSensitiveComparer s_ordinal = new OrdinalCaseSensitiveComparer ( ) ;
1820 private static readonly OrdinalIgnoreCaseComparer s_ordinalIgnoreCase = new OrdinalIgnoreCaseComparer ( ) ;
1921
2022 public static StringComparer InvariantCulture
@@ -170,30 +172,33 @@ public int GetHashCode(object obj)
170172 }
171173
172174 [ Serializable ]
175+ [ System . Runtime . CompilerServices . TypeForwardedFrom ( "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" ) ]
173176 internal sealed class CultureAwareComparer : StringComparer
174177 {
175- private readonly CompareInfo _compareInfo ;
176- private readonly CompareOptions _options ;
178+ private readonly CompareInfo _compareInfo ; // Do not rename (binary serialization)
179+ private readonly bool _ignoreCase ; // Do not rename (binary serialization)
177180
178181 internal CultureAwareComparer ( CultureInfo culture , bool ignoreCase )
179182 {
180183 _compareInfo = culture . CompareInfo ;
181- _options = ignoreCase ? CompareOptions . IgnoreCase : CompareOptions . None ;
184+ _ignoreCase = ignoreCase ;
182185 }
183186
187+ private CompareOptions Options => _ignoreCase ? CompareOptions . IgnoreCase : CompareOptions . None ;
188+
184189 public override int Compare ( string x , string y )
185190 {
186191 if ( object . ReferenceEquals ( x , y ) ) return 0 ;
187192 if ( x == null ) return - 1 ;
188193 if ( y == null ) return 1 ;
189- return _compareInfo . Compare ( x , y , _options ) ;
194+ return _compareInfo . Compare ( x , y , Options ) ;
190195 }
191196
192197 public override bool Equals ( string x , string y )
193198 {
194199 if ( object . ReferenceEquals ( x , y ) ) return true ;
195200 if ( x == null || y == null ) return false ;
196- return _compareInfo . Compare ( x , y , _options ) == 0 ;
201+ return _compareInfo . Compare ( x , y , Options ) == 0 ;
197202 }
198203
199204 public override int GetHashCode ( string obj )
@@ -202,7 +207,7 @@ public override int GetHashCode(string obj)
202207 {
203208 throw new ArgumentNullException ( nameof ( obj ) ) ;
204209 }
205- return _compareInfo . GetHashCodeOfString ( obj , _options ) ;
210+ return _compareInfo . GetHashCodeOfString ( obj , Options ) ;
206211 }
207212
208213 // Equals method for the comparer itself.
@@ -211,20 +216,108 @@ public override bool Equals(object obj)
211216 CultureAwareComparer comparer = obj as CultureAwareComparer ;
212217 return
213218 comparer != null &&
214- _options == comparer . _options &&
219+ _ignoreCase == comparer . _ignoreCase &&
215220 _compareInfo . Equals ( comparer . _compareInfo ) ;
216221 }
217222
218223 public override int GetHashCode ( )
219224 {
220225 int hashCode = _compareInfo . GetHashCode ( ) ;
221- return _options == CompareOptions . None ? hashCode : ~ hashCode ;
226+ return _ignoreCase ? ~ hashCode : hashCode ;
227+ }
228+ }
229+
230+ [ Serializable ]
231+ [ System . Runtime . CompilerServices . TypeForwardedFrom ( "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" ) ]
232+ internal class OrdinalComparer : StringComparer
233+ {
234+ private readonly bool _ignoreCase ; // Do not rename (binary serialization)
235+
236+ internal OrdinalComparer ( bool ignoreCase )
237+ {
238+ _ignoreCase = ignoreCase ;
239+ }
240+
241+ public override int Compare ( string x , string y )
242+ {
243+ if ( ReferenceEquals ( x , y ) )
244+ return 0 ;
245+ if ( x == null )
246+ return - 1 ;
247+ if ( y == null )
248+ return 1 ;
249+
250+ if ( _ignoreCase )
251+ {
252+ return string . Compare ( x , y , StringComparison . OrdinalIgnoreCase ) ;
253+ }
254+
255+ return string . CompareOrdinal ( x , y ) ;
256+ }
257+
258+ public override bool Equals ( string x , string y )
259+ {
260+ if ( ReferenceEquals ( x , y ) )
261+ return true ;
262+ if ( x == null || y == null )
263+ return false ;
264+
265+ if ( _ignoreCase )
266+ {
267+ if ( x . Length != y . Length )
268+ {
269+ return false ;
270+ }
271+ return ( string . Compare ( x , y , StringComparison . OrdinalIgnoreCase ) == 0 ) ;
272+ }
273+ return x . Equals ( y ) ;
274+ }
275+
276+ public override int GetHashCode ( string obj )
277+ {
278+ if ( obj == null )
279+ {
280+ #if CORECLR
281+ ThrowHelper . ThrowArgumentNullException ( ExceptionArgument . obj ) ;
282+ #else
283+ throw new ArgumentNullException ( nameof ( obj ) ) ;
284+ #endif
285+ }
286+ Contract . EndContractBlock ( ) ;
287+
288+ if ( _ignoreCase )
289+ {
290+ return TextInfo . GetHashCodeOrdinalIgnoreCase ( obj ) ;
291+ }
292+
293+ return obj . GetHashCode ( ) ;
294+ }
295+
296+ // Equals method for the comparer itself.
297+ public override bool Equals ( object obj )
298+ {
299+ OrdinalComparer comparer = obj as OrdinalComparer ;
300+ if ( comparer == null )
301+ {
302+ return false ;
303+ }
304+ return ( this . _ignoreCase == comparer . _ignoreCase ) ;
305+ }
306+
307+ public override int GetHashCode ( )
308+ {
309+ int hashCode = nameof ( OrdinalComparer ) . GetHashCode ( ) ;
310+ return _ignoreCase ? ( ~ hashCode ) : hashCode ;
222311 }
223312 }
224313
225314 [ Serializable ]
226- internal sealed class OrdinalComparer : StringComparer
315+ internal sealed class OrdinalCaseSensitiveComparer : OrdinalComparer , ISerializable
227316 {
317+ public OrdinalCaseSensitiveComparer ( ) : base ( false )
318+ {
319+ }
320+
228321 public override int Compare ( string x , string y ) => string . CompareOrdinal ( x , y ) ;
229322
230323 public override bool Equals ( string x , string y ) => string . Equals ( x , y ) ;
@@ -242,14 +335,20 @@ public override int GetHashCode(string obj)
242335 return obj . GetHashCode ( ) ;
243336 }
244337
245- // Equals/GetHashCode methods for the comparer itself.
246- public override bool Equals ( object obj ) => obj is OrdinalComparer ;
247- public override int GetHashCode ( ) => nameof ( OrdinalComparer ) . GetHashCode ( ) ;
338+ public void GetObjectData ( SerializationInfo info , StreamingContext context )
339+ {
340+ info . SetType ( typeof ( OrdinalComparer ) ) ;
341+ info . AddValue ( "_ignoreCase" , false ) ;
342+ }
248343 }
249344
250- [ Serializable ]
251- internal sealed class OrdinalIgnoreCaseComparer : StringComparer
345+ [ Serializable ]
346+ internal sealed class OrdinalIgnoreCaseComparer : OrdinalComparer , ISerializable
252347 {
348+ public OrdinalIgnoreCaseComparer ( ) : base ( true )
349+ {
350+ }
351+
253352 public override int Compare ( string x , string y ) => string . Compare ( x , y , StringComparison . OrdinalIgnoreCase ) ;
254353
255354 public override bool Equals ( string x , string y ) => string . Equals ( x , y , StringComparison . OrdinalIgnoreCase ) ;
@@ -267,8 +366,10 @@ public override int GetHashCode(string obj)
267366 return TextInfo . GetHashCodeOrdinalIgnoreCase ( obj ) ;
268367 }
269368
270- // Equals/GetHashCode methods for the comparer itself.
271- public override bool Equals ( object obj ) => obj is OrdinalIgnoreCaseComparer ;
272- public override int GetHashCode ( ) => nameof ( OrdinalIgnoreCaseComparer ) . GetHashCode ( ) ;
369+ public void GetObjectData ( SerializationInfo info , StreamingContext context )
370+ {
371+ info . SetType ( typeof ( OrdinalComparer ) ) ;
372+ info . AddValue ( "_ignoreCase" , true ) ;
373+ }
273374 }
274375}
0 commit comments