@@ -13,8 +13,8 @@ namespace System
1313 [ System . Runtime . CompilerServices . TypeForwardedFrom ( "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" ) ]
1414 public abstract class StringComparer : IComparer , IEqualityComparer , IComparer < string > , IEqualityComparer < string >
1515 {
16- private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer ( CultureInfo . InvariantCulture , false ) ;
17- private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer ( CultureInfo . InvariantCulture , true ) ;
16+ private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer ( CultureInfo . InvariantCulture , CompareOptions . None ) ;
17+ private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer ( CultureInfo . InvariantCulture , CompareOptions . IgnoreCase ) ;
1818 private static readonly OrdinalCaseSensitiveComparer s_ordinal = new OrdinalCaseSensitiveComparer ( ) ;
1919 private static readonly OrdinalIgnoreCaseComparer s_ordinalIgnoreCase = new OrdinalIgnoreCaseComparer ( ) ;
2020
@@ -38,15 +38,15 @@ public static StringComparer CurrentCulture
3838 {
3939 get
4040 {
41- return new CultureAwareComparer ( CultureInfo . CurrentCulture , false ) ;
41+ return new CultureAwareComparer ( CultureInfo . CurrentCulture , CompareOptions . None ) ;
4242 }
4343 }
4444
4545 public static StringComparer CurrentCultureIgnoreCase
4646 {
4747 get
4848 {
49- return new CultureAwareComparer ( CultureInfo . CurrentCulture , true ) ;
49+ return new CultureAwareComparer ( CultureInfo . CurrentCulture , CompareOptions . IgnoreCase ) ;
5050 }
5151 }
5252
@@ -94,8 +94,18 @@ public static StringComparer Create(CultureInfo culture, bool ignoreCase)
9494 {
9595 throw new ArgumentNullException ( nameof ( culture ) ) ;
9696 }
97+
98+ return new CultureAwareComparer ( culture , ignoreCase ? CompareOptions . IgnoreCase : CompareOptions . None ) ;
99+ }
100+
101+ public static StringComparer Create ( CultureInfo culture , CompareOptions options )
102+ {
103+ if ( culture == null )
104+ {
105+ throw new ArgumentException ( nameof ( culture ) ) ;
106+ }
97107
98- return new CultureAwareComparer ( culture , ignoreCase ) ;
108+ return new CultureAwareComparer ( culture , options ) ;
99109 }
100110
101111 public int Compare ( object x , object y )
@@ -123,7 +133,6 @@ public int Compare(object x, object y)
123133 throw new ArgumentException ( SR . Argument_ImplementIComparable ) ;
124134 }
125135
126-
127136 public new bool Equals ( Object x , Object y )
128137 {
129138 if ( x == y ) return true ;
@@ -163,32 +172,50 @@ public int GetHashCode(object obj)
163172
164173 [ Serializable ]
165174 [ System . Runtime . CompilerServices . TypeForwardedFrom ( "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" ) ]
166- public sealed class CultureAwareComparer : StringComparer
175+ public sealed class CultureAwareComparer : StringComparer , ISerializable
167176 {
177+ private const CompareOptions ValidCompareMaskOffFlags = ~ ( CompareOptions . IgnoreCase | CompareOptions . IgnoreSymbols | CompareOptions . IgnoreNonSpace | CompareOptions . IgnoreWidth | CompareOptions . IgnoreKanaType | CompareOptions . StringSort ) ;
178+
168179 private readonly CompareInfo _compareInfo ; // Do not rename (binary serialization)
169- private readonly bool _ignoreCase ; // Do not rename (binary serialization)
180+ private CompareOptions _options ;
170181
171- internal CultureAwareComparer ( CultureInfo culture , bool ignoreCase )
182+ internal CultureAwareComparer ( CultureInfo culture , CompareOptions compareOptions )
172183 {
173184 _compareInfo = culture . CompareInfo ;
174- _ignoreCase = ignoreCase ;
185+
186+ if ( ( compareOptions & CultureAwareComparer . ValidCompareMaskOffFlags ) != 0 )
187+ {
188+ throw new ArgumentException ( SR . Argument_InvalidFlag , nameof ( compareOptions ) ) ;
189+ }
190+ _options = compareOptions ;
175191 }
176192
177- private CompareOptions Options => _ignoreCase ? CompareOptions . IgnoreCase : CompareOptions . None ;
193+ private CultureAwareComparer ( SerializationInfo info , StreamingContext context )
194+ {
195+ _compareInfo = ( CompareInfo ) info . GetValue ( "_compareInfo" , typeof ( CompareInfo ) ) ;
196+ bool ignoreCase = info . GetBoolean ( "_ignoreCase" ) ;
197+
198+ var obj = info . GetValueNoThrow ( "_options" , typeof ( CompareOptions ) ) ;
199+ if ( obj != null )
200+ _options = ( CompareOptions ) obj ;
201+
202+ // fix up the _options value in case we are getting old serialized object not having _options
203+ _options |= ignoreCase ? CompareOptions . IgnoreCase : CompareOptions . None ;
204+ }
178205
179206 public override int Compare ( string x , string y )
180207 {
181208 if ( object . ReferenceEquals ( x , y ) ) return 0 ;
182209 if ( x == null ) return - 1 ;
183210 if ( y == null ) return 1 ;
184- return _compareInfo . Compare ( x , y , Options ) ;
211+ return _compareInfo . Compare ( x , y , _options ) ;
185212 }
186213
187214 public override bool Equals ( string x , string y )
188215 {
189216 if ( object . ReferenceEquals ( x , y ) ) return true ;
190217 if ( x == null || y == null ) return false ;
191- return _compareInfo . Compare ( x , y , Options ) == 0 ;
218+ return _compareInfo . Compare ( x , y , _options ) == 0 ;
192219 }
193220
194221 public override int GetHashCode ( string obj )
@@ -197,7 +224,7 @@ public override int GetHashCode(string obj)
197224 {
198225 throw new ArgumentNullException ( nameof ( obj ) ) ;
199226 }
200- return _compareInfo . GetHashCodeOfString ( obj , Options ) ;
227+ return _compareInfo . GetHashCodeOfString ( obj , _options ) ;
201228 }
202229
203230 // Equals method for the comparer itself.
@@ -206,14 +233,20 @@ public override bool Equals(object obj)
206233 CultureAwareComparer comparer = obj as CultureAwareComparer ;
207234 return
208235 comparer != null &&
209- _ignoreCase == comparer . _ignoreCase &&
236+ _options == comparer . _options &&
210237 _compareInfo . Equals ( comparer . _compareInfo ) ;
211238 }
212239
213240 public override int GetHashCode ( )
214241 {
215- int hashCode = _compareInfo . GetHashCode ( ) ;
216- return _ignoreCase ? ~ hashCode : hashCode ;
242+ return _compareInfo . GetHashCode ( ) ^ ( ( int ) _options & 0x7FFFFFFF ) ;
243+ }
244+
245+ public void GetObjectData ( SerializationInfo info , StreamingContext context )
246+ {
247+ info . AddValue ( "_compareInfo" , _compareInfo ) ;
248+ info . AddValue ( "_options" , _options ) ;
249+ info . AddValue ( "_ignoreCase" , ( _options & CompareOptions . IgnoreCase ) != 0 ) ;
217250 }
218251 }
219252
0 commit comments