Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 7995334

Browse files
Anipiktarekgh
authored andcommitted
StringComparer Create(culture, CompareOptions) overload (#16334)
* String Create options overlaod * Minor Change * Feedback * validation on options * obsolete removed * Implementing Iserializable and removing ignorecase * HashCode and serialization changes * made inline * Space Corrected
1 parent 24b4aff commit 7995334

File tree

1 file changed

+50
-17
lines changed

1 file changed

+50
-17
lines changed

src/mscorlib/shared/System/StringComparer.cs

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)