The Labs \ Source Viewer \ SSCLI \ System \ CultureAwareComparer

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System
  16. {
  17.     using System.Collections;
  18.     using System.Collections.Generic;
  19.     using System.Globalization;
  20.    
  21.     [Serializable()]
  22.     [System.Runtime.InteropServices.ComVisible(true)]
  23.     public abstract class StringComparer : IComparer, IEqualityComparer, IComparer<string>, IEqualityComparer<string>
  24.     {
  25.         private static StringComparer _invariantCulture = new CultureAwareComparer(CultureInfo.InvariantCulture, false);
  26.         private static StringComparer _invariantCultureIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture, true);
  27.         private static StringComparer _ordinal = new OrdinalComparer(false);
  28.         private static StringComparer _ordinalIgnoreCase = new OrdinalComparer(true);
  29.        
  30.         public static StringComparer InvariantCulture {
  31.             get { return _invariantCulture; }
  32.         }
  33.        
  34.         public static StringComparer InvariantCultureIgnoreCase {
  35.             get { return _invariantCultureIgnoreCase; }
  36.         }
  37.        
  38.         public static StringComparer CurrentCulture {
  39.             get { return new CultureAwareComparer(CultureInfo.CurrentCulture, false); }
  40.         }
  41.        
  42.         public static StringComparer CurrentCultureIgnoreCase {
  43.             get { return new CultureAwareComparer(CultureInfo.CurrentCulture, true); }
  44.         }
  45.        
  46.         public static StringComparer Ordinal {
  47.             get { return _ordinal; }
  48.         }
  49.        
  50.         public static StringComparer OrdinalIgnoreCase {
  51.             get { return _ordinalIgnoreCase; }
  52.         }
  53.        
  54.         public static StringComparer Create(CultureInfo culture, bool ignoreCase)
  55.         {
  56.             if (culture == null) {
  57.                 throw new ArgumentNullException("culture");
  58.             }
  59.            
  60.             return new CultureAwareComparer(culture, ignoreCase);
  61.         }
  62.        
  63.         public int Compare(object x, object y)
  64.         {
  65.             if (x == y)
  66.                 return 0;
  67.             if (x == null)
  68.                 return -1;
  69.             if (y == null)
  70.                 return 1;
  71.            
  72.             string sa = x as string;
  73.             if (sa != null) {
  74.                 string sb = y as string;
  75.                 if (sb != null) {
  76.                     return Compare(sa, sb);
  77.                 }
  78.             }
  79.            
  80.             IComparable ia = x as IComparable;
  81.             if (ia != null) {
  82.                 return ia.CompareTo(y);
  83.             }
  84.            
  85.             throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
  86.         }
  87.        
  88.        
  89.         public new bool Equals(object x, object y)
  90.         {
  91.             if (x == y)
  92.                 return true;
  93.             if (x == null || y == null)
  94.                 return false;
  95.            
  96.             string sa = x as string;
  97.             if (sa != null) {
  98.                 string sb = y as string;
  99.                 if (sb != null) {
  100.                     return Equals(sa, sb);
  101.                 }
  102.             }
  103.             return x.Equals(y);
  104.         }
  105.        
  106.         public int GetHashCode(object obj)
  107.         {
  108.             if (obj == null) {
  109.                 throw new ArgumentNullException("obj");
  110.             }
  111.            
  112.             string s = obj as string;
  113.             if (s != null) {
  114.                 return GetHashCode(s);
  115.             }
  116.             return obj.GetHashCode();
  117.         }
  118.        
  119.         public abstract int Compare(string x, string y);
  120.         public abstract bool Equals(string x, string y);
  121.         public abstract int GetHashCode(string obj);
  122.     }
  123.    
  124.     [Serializable()]
  125.     internal sealed class CultureAwareComparer : StringComparer
  126.     {
  127.         private CompareInfo _compareInfo;
  128.         private bool _ignoreCase;
  129.        
  130.         internal CultureAwareComparer(CultureInfo culture, bool ignoreCase)
  131.         {
  132.             _compareInfo = culture.CompareInfo;
  133.             _ignoreCase = ignoreCase;
  134.         }
  135.        
  136.         public override int Compare(string x, string y)
  137.         {
  138.             if (Object.ReferenceEquals(x, y))
  139.                 return 0;
  140.             if (x == null)
  141.                 return -1;
  142.             if (y == null)
  143.                 return 1;
  144.             return _compareInfo.Compare(x, y, _ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);
  145.         }
  146.        
  147.         public override bool Equals(string x, string y)
  148.         {
  149.             if (Object.ReferenceEquals(x, y))
  150.                 return true;
  151.             if (x == null || y == null)
  152.                 return false;
  153.            
  154.             return (_compareInfo.Compare(x, y, _ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None) == 0);
  155.         }
  156.        
  157.         public override int GetHashCode(string obj)
  158.         {
  159.             if (obj == null) {
  160.                 throw new ArgumentNullException("obj");
  161.             }
  162.            
  163.             if (_ignoreCase) {
  164.                 return _compareInfo.GetHashCodeOfString(obj, CompareOptions.IgnoreCase);
  165.             }
  166.            
  167.             return _compareInfo.GetHashCodeOfString(obj, CompareOptions.None);
  168.         }
  169.        
  170.         // Equals method for the comparer itself.
  171.         public override bool Equals(object obj)
  172.         {
  173.             CultureAwareComparer comparer = obj as CultureAwareComparer;
  174.             if (comparer == null) {
  175.                 return false;
  176.             }
  177.             return (this._ignoreCase == comparer._ignoreCase) && (this._compareInfo.Equals(comparer._compareInfo));
  178.         }
  179.        
  180.         public override int GetHashCode()
  181.         {
  182.             int hashCode = _compareInfo.GetHashCode();
  183.             return _ignoreCase ? (~hashCode) : hashCode;
  184.         }
  185.     }
  186.    
  187.    
  188.     // Provide x more optimal implementation of ordinal comparison.
  189.     [Serializable()]
  190.     internal sealed class OrdinalComparer : StringComparer
  191.     {
  192.         private bool _ignoreCase;
  193.        
  194.         internal OrdinalComparer(bool ignoreCase)
  195.         {
  196.             _ignoreCase = ignoreCase;
  197.         }
  198.        
  199.         public override int Compare(string x, string y)
  200.         {
  201.             if (Object.ReferenceEquals(x, y))
  202.                 return 0;
  203.             if (x == null)
  204.                 return -1;
  205.             if (y == null)
  206.                 return 1;
  207.            
  208.             if (_ignoreCase) {
  209.                 return TextInfo.CompareOrdinalIgnoreCase(x, y);
  210.             }
  211.            
  212.             return String.CompareOrdinal(x, y);
  213.         }
  214.        
  215.         public override bool Equals(string x, string y)
  216.         {
  217.             if (Object.ReferenceEquals(x, y))
  218.                 return true;
  219.             if (x == null || y == null)
  220.                 return false;
  221.            
  222.             if (_ignoreCase) {
  223.                 if (x.Length != y.Length) {
  224.                     return false;
  225.                 }
  226.                 return (TextInfo.CompareOrdinalIgnoreCase(x, y) == 0);
  227.             }
  228.             return x.Equals(y);
  229.         }
  230.        
  231.         public override int GetHashCode(string obj)
  232.         {
  233.             if (obj == null) {
  234.                 throw new ArgumentNullException("obj");
  235.             }
  236.            
  237.             if (_ignoreCase) {
  238.                 return TextInfo.GetHashCodeOrdinalIgnoreCase(obj);
  239.             }
  240.            
  241.             return obj.GetHashCode();
  242.         }
  243.        
  244.         // Equals method for the comparer itself.
  245.         public override bool Equals(object obj)
  246.         {
  247.             OrdinalComparer comparer = obj as OrdinalComparer;
  248.             if (comparer == null) {
  249.                 return false;
  250.             }
  251.             return (this._ignoreCase == comparer._ignoreCase);
  252.         }
  253.        
  254.         public override int GetHashCode()
  255.         {
  256.             string name = "OrdinalComparer";
  257.             int hashCode = name.GetHashCode();
  258.             return _ignoreCase ? (~hashCode) : hashCode;
  259.         }
  260.     }
  261. }

Developer Fusion