[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public abstract class StringComparer : IComparer, IEqualityComparer, IComparer<string>, IEqualityComparer<string>
{
- private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer(CultureInfo.InvariantCulture, false);
- private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture, true);
+ private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer(CultureInfo.InvariantCulture, CompareOptions.None);
+ private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture, CompareOptions.IgnoreCase);
private static readonly OrdinalCaseSensitiveComparer s_ordinal = new OrdinalCaseSensitiveComparer();
private static readonly OrdinalIgnoreCaseComparer s_ordinalIgnoreCase = new OrdinalIgnoreCaseComparer();
{
get
{
- return new CultureAwareComparer(CultureInfo.CurrentCulture, false);
+ return new CultureAwareComparer(CultureInfo.CurrentCulture, CompareOptions.None);
}
}
{
get
{
- return new CultureAwareComparer(CultureInfo.CurrentCulture, true);
+ return new CultureAwareComparer(CultureInfo.CurrentCulture, CompareOptions.IgnoreCase);
}
}
{
throw new ArgumentNullException(nameof(culture));
}
+
+ return new CultureAwareComparer(culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);
+ }
+
+ public static StringComparer Create(CultureInfo culture, CompareOptions options)
+ {
+ if (culture == null)
+ {
+ throw new ArgumentException(nameof(culture));
+ }
- return new CultureAwareComparer(culture, ignoreCase);
+ return new CultureAwareComparer(culture, options);
}
public int Compare(object x, object y)
throw new ArgumentException(SR.Argument_ImplementIComparable);
}
-
public new bool Equals(Object x, Object y)
{
if (x == y) return true;
[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
- public sealed class CultureAwareComparer : StringComparer
+ public sealed class CultureAwareComparer : StringComparer, ISerializable
{
+ private const CompareOptions ValidCompareMaskOffFlags = ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);
+
private readonly CompareInfo _compareInfo; // Do not rename (binary serialization)
- private readonly bool _ignoreCase; // Do not rename (binary serialization)
+ private CompareOptions _options;
- internal CultureAwareComparer(CultureInfo culture, bool ignoreCase)
+ internal CultureAwareComparer(CultureInfo culture, CompareOptions compareOptions)
{
_compareInfo = culture.CompareInfo;
- _ignoreCase = ignoreCase;
+
+ if ((compareOptions & CultureAwareComparer.ValidCompareMaskOffFlags) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(compareOptions));
+ }
+ _options = compareOptions;
}
- private CompareOptions Options => _ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None;
+ private CultureAwareComparer(SerializationInfo info, StreamingContext context)
+ {
+ _compareInfo = (CompareInfo)info.GetValue("_compareInfo", typeof(CompareInfo));
+ bool ignoreCase = info.GetBoolean("_ignoreCase");
+
+ var obj = info.GetValueNoThrow("_options", typeof(CompareOptions));
+ if (obj != null)
+ _options = (CompareOptions)obj;
+
+ // fix up the _options value in case we are getting old serialized object not having _options
+ _options |= ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None;
+ }
public override int Compare(string x, string y)
{
if (object.ReferenceEquals(x, y)) return 0;
if (x == null) return -1;
if (y == null) return 1;
- return _compareInfo.Compare(x, y, Options);
+ return _compareInfo.Compare(x, y, _options);
}
public override bool Equals(string x, string y)
{
if (object.ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
- return _compareInfo.Compare(x, y, Options) == 0;
+ return _compareInfo.Compare(x, y, _options) == 0;
}
public override int GetHashCode(string obj)
{
throw new ArgumentNullException(nameof(obj));
}
- return _compareInfo.GetHashCodeOfString(obj, Options);
+ return _compareInfo.GetHashCodeOfString(obj, _options);
}
// Equals method for the comparer itself.
CultureAwareComparer comparer = obj as CultureAwareComparer;
return
comparer != null &&
- _ignoreCase == comparer._ignoreCase &&
+ _options == comparer._options &&
_compareInfo.Equals(comparer._compareInfo);
}
public override int GetHashCode()
{
- int hashCode = _compareInfo.GetHashCode();
- return _ignoreCase ? ~hashCode : hashCode;
+ return _compareInfo.GetHashCode() ^ ((int)_options & 0x7FFFFFFF);
+ }
+
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ info.AddValue("_compareInfo", _compareInfo);
+ info.AddValue("_options", _options);
+ info.AddValue("_ignoreCase", (_options & CompareOptions.IgnoreCase) != 0);
}
}