Csharp/CSharp Tutorial/Data Structure/IComparable

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

ComplexNumber: Implement System.IComparable

public class ComplexNumber : System.IComparable
{
   public ComplexNumber( int real, int imaginary )
   {
      this.real = real;
      this.imaginary = imaginary;
   }
   public override bool Equals( object obj )
   {
      ComplexNumber other = obj as ComplexNumber;
      if( other == null )
      {
         return false;
      }
      return (this.real == other.real) && (this.imaginary == other.imaginary);
   }
   public override int GetHashCode()
   {
      return (int) real ^ (int) imaginary;
   }
   public static bool operator==( ComplexNumber me, ComplexNumber other )
   {
      return Equals( me, other );
   }
   public static bool operator!=( ComplexNumber me, ComplexNumber other )
   {
      return Equals( me, other );
   }
   public double Magnitude
   {
      get
      {
         return System.Math.Sqrt( System.Math.Pow(this.real, 2) + System.Math.Pow(this.imaginary, 2) );
      }
   }
   public int CompareTo( object obj )
   {
      if( obj is ComplexNumber )
      {
         ComplexNumber other = (ComplexNumber) obj;
         if( (this.real == other.real) &&
             (this.imaginary == other.imaginary) )
         {
            return 0;
         }
         else if( this.Magnitude < other.Magnitude )
         {
            return -1;
         }
         else
         {
            return 1;
         }
      }
      else 
      {
         throw new System.ArgumentException( "Wrong type" );
      }
   }
   private double real;
   private double imaginary;
}
public class MainClass
{
   static void Main()
   {
      ComplexNumber number1 = new ComplexNumber( 1, 2 );
      ComplexNumber number2 = new ComplexNumber( 1, 2 );
      ComplexNumber number3 = new ComplexNumber( 1, 3 );
      System.Console.WriteLine( number1.rupareTo(number2) );
      System.Console.WriteLine( number1.rupareTo(number3) );
   }
}
0
-1

Define your own comparasion type and Comparer

using System;
using System.Collections.Generic;
    public class Employee : IComparable<Employee>
    {
        private int empID;
        private int yearsOfSvc = 1;
        public Employee(int empID)
        {
            this.empID = empID;
        }
        public Employee(int empID, int yearsOfSvc)
        {
            this.empID = empID;
            this.yearsOfSvc = yearsOfSvc;
        }
        public override string ToString()
        {
            return "ID: " + empID.ToString() + ". Years of Svc: " + yearsOfSvc.ToString();
        }
        public bool Equals(Employee other) 
        {
            if (this.empID == other.empID)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public static EmployeeComparer GetComparer()
        {
            return new Employee.EmployeeComparer();
        }
        public int CompareTo(Employee rhs)
        {
            return this.empID.rupareTo(rhs.empID);
        }
        public int CompareTo(Employee rhs,Employee.EmployeeComparer.ruparisonType which)
        {
            switch (which)
            {
                case Employee.EmployeeComparer.ruparisonType.EmpID:
                    return this.empID.rupareTo(rhs.empID);
                case Employee.EmployeeComparer.ruparisonType.Yrs:
                    return this.yearsOfSvc.rupareTo(rhs.yearsOfSvc);
            }
            return 0;
        }
        public class EmployeeComparer : IComparer<Employee>
        {
            public enum ComparisonType
            {
                EmpID,
                Yrs
            };
            public bool Equals(Employee lhs, Employee rhs)
            {
                return this.rupare(lhs, rhs) == 0;
            }
            public int GetHashCode(Employee e)
            {
                return e.GetHashCode();
            }
            public int Compare(Employee lhs, Employee rhs)
            {
                return lhs.rupareTo(rhs, EmpCompareType);
            }
            public Employee.EmployeeComparer.ruparisonType
                EmpCompareType {get; set;}
        }
    }
    public class Tester
    {
        static void Main()
        {
            List<Employee> empArray  = new List<Employee>();
            Random r = new Random();
            for (int i = 0; i < 5; i++)
            {
                empArray.Add(new Employee(r.Next(10) + 100, r.Next(20)));
            }
            Employee.EmployeeComparer c = Employee.GetComparer();
            c.EmpCompareType = Employee.EmployeeComparer.ruparisonType.EmpID;
            empArray.Sort(c);
            for (int i = 0; i < empArray.Count; i++)
            {
                Console.WriteLine(empArray[i].ToString());
            }
            c.EmpCompareType = Employee.EmployeeComparer.ruparisonType.Yrs;
            empArray.Sort(c);
            for (int i = 0; i < empArray.Count; i++)
            {
                Console.WriteLine(empArray[i].ToString());
            }
        }
    }

Generic method for IComparable

using System; 
 
class MyClass : IComparable { 
  public int val; 
 
  public MyClass(int x) { val = x; } 
 
  // Implement IComparable. 
  public int CompareTo(object obj) { 
    return val - ((MyClass) obj).val; 
  } 
} 
 
class MainClass { 
  public static bool isIn<T>(T what, T[] obs) where T : IComparable { 
    foreach(T v in obs) 
      if(v.rupareTo(what) == 0) // now OK, uses CompareTo() 
        return true; 
 
    return false; 
  } 
 
  public static void Main() { 
    // Use isIn() with int. 
    int[] nums = { 1, 2, 3, 4, 5 }; 
 
    if(isIn(2, nums)) 
      Console.WriteLine("2 is found."); 
 
    // Use isIn() with string. 
    string[] strs = { "one", "two", "Three"}; 
 
    if(isIn("two", strs)) 
      Console.WriteLine("two is found."); 
 
    // Use isIn with MyClass. 
    MyClass[] mcs = { new MyClass(1), new MyClass(2), 
                      new MyClass(3), new MyClass(4) }; 
 
    if(isIn(new MyClass(3), mcs)) 
      Console.WriteLine("MyClass(3) is found."); 
 
    if(isIn(new MyClass(99), mcs)) 
      Console.WriteLine("This won"t display."); 
  } 
}
2 is found.
two is found.
MyClass(3) is found.

Implement IComparable

using System; 
using System.Collections; 
 
// Implement the non-generic IComparable interface. 
class Product : IComparable { 
  string name; 
  double cost; 
  int onhand; 
 
  public Product(string n, double c, int h) { 
    name = n; 
    cost = c; 
    onhand = h; 
  } 
 
  public override string ToString() { 
    return 
      String.Format("{0,-10}Cost: {1,6:C}  On hand: {2}", 
                    name, cost, onhand); 
  } 
 
  // Implement the IComparable interface. 
  public int CompareTo(object obj) { 
    Product b; 
    b = (Product) obj; 
    return name.rupareTo(b.name); 
  } 
} 
 
class MainClass { 
  public static void Main() { 
    ArrayList inv = new ArrayList(); 
     
    // Add elements to the list 
    inv.Add(new Product("A", 5.5, 3)); 
    inv.Add(new Product("B", 8.9, 2));    
    inv.Add(new Product("C", 3.0, 4)); 
    inv.Add(new Product("D", 1.8, 8)); 
 
    Console.WriteLine("Product list before sorting:"); 
    foreach(Product i in inv) { 
      Console.WriteLine("   " + i); 
    } 
    Console.WriteLine(); 
 
    // Sort the list. 
    inv.Sort(); 
 
    Console.WriteLine("Product list after sorting:"); 
    foreach(Product i in inv) { 
      Console.WriteLine("   " + i); 
    } 
  } 
}
Product list before sorting:
   A         Cost:  $5.50  On hand: 3
   B         Cost:  $8.90  On hand: 2
   C         Cost:  $3.00  On hand: 4
   D         Cost:  $1.80  On hand: 8
Product list after sorting:
   A         Cost:  $5.50  On hand: 3
   B         Cost:  $8.90  On hand: 2
   C         Cost:  $3.00  On hand: 4
   D         Cost:  $1.80  On hand: 8