2 // System.StringComparer
5 // Marek Safar (marek.safar@seznam.cz)
7 // (C) 2005 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Globalization;
34 using System.Runtime.InteropServices;
35 using System.Collections.Generic;
39 [Serializable, ComVisible(true)]
40 public abstract class StringComparer : IComparer, IEqualityComparer, IComparer<string>, IEqualityComparer<string>
42 static StringComparer invariantCultureIgnoreCase = new CultureAwareComparer (CultureInfo.InvariantCulture, true);
43 static StringComparer invariantCulture = new CultureAwareComparer (CultureInfo.InvariantCulture, false);
44 static StringComparer ordinalIgnoreCase = new OrdinalComparer (true);
45 static StringComparer ordinal = new OrdinalComparer (false);
48 protected StringComparer ()
53 public static StringComparer CurrentCulture {
55 return new CultureAwareComparer (CultureInfo.CurrentCulture, false);
59 public static StringComparer CurrentCultureIgnoreCase {
61 return new CultureAwareComparer (CultureInfo.CurrentCulture, true);
65 public static StringComparer InvariantCulture {
67 return invariantCulture;
71 public static StringComparer InvariantCultureIgnoreCase {
73 return invariantCultureIgnoreCase;
77 public static StringComparer Ordinal {
78 get { return ordinal; }
81 public static StringComparer OrdinalIgnoreCase {
82 get { return ordinalIgnoreCase; }
86 public static StringComparer Create (CultureInfo culture, bool ignoreCase)
89 throw new ArgumentNullException ("culture");
91 return new CultureAwareComparer (culture, ignoreCase);
94 public int Compare (object x, object y)
103 string s_x = x as string;
105 string s_y = y as string;
107 return Compare (s_x, s_y);
110 IComparable ic = x as IComparable;
112 throw new ArgumentException ();
114 return ic.CompareTo (y);
117 public new bool Equals (object x, object y)
121 if (x == null || y == null)
124 string s_x = x as string;
126 string s_y = y as string;
128 return Equals (s_x, s_y);
133 public int GetHashCode (object obj)
136 throw new ArgumentNullException("obj");
138 string s = obj as string;
139 return s == null ? obj.GetHashCode (): GetHashCode(s);
142 public abstract int Compare (string x, string y);
143 public abstract bool Equals (string x, string y);
144 public abstract int GetHashCode (string obj);
148 class CultureAwareComparer : StringComparer
150 readonly bool _ignoreCase;
151 readonly CompareInfo _compareInfo;
153 public CultureAwareComparer (CultureInfo ci, bool ignore_case)
155 _compareInfo = ci.CompareInfo;
156 _ignoreCase = ignore_case;
159 public override int Compare (string x, string y)
161 CompareOptions co = _ignoreCase ? CompareOptions.IgnoreCase :
163 return _compareInfo.Compare (x, y, co);
166 public override bool Equals (string x, string y)
168 return Compare (x, y) == 0;
171 public override int GetHashCode (string s)
174 throw new ArgumentNullException("s");
176 CompareOptions co = _ignoreCase ? CompareOptions.IgnoreCase :
178 return _compareInfo.GetSortKey (s, co).GetHashCode ();
183 internal class OrdinalComparer : StringComparer
185 readonly bool _ignoreCase;
187 public OrdinalComparer (bool ignoreCase)
189 _ignoreCase = ignoreCase;
192 public override int Compare (string x, string y)
195 return String.CompareOrdinalCaseInsensitiveUnchecked (x, 0, Int32.MaxValue, y, 0, Int32.MaxValue);
197 return String.CompareOrdinalUnchecked (x, 0, Int32.MaxValue, y, 0, Int32.MaxValue);
200 public override bool Equals (string x, string y)
203 return Compare (x, y) == 0;
208 public override int GetHashCode (string s)
211 return s.GetCaseInsensitiveHashCode ();
213 return s.GetHashCode ();