Csharp/CSharp Tutorial/Data Structure/IComparable

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

ComplexNumber: Implement System.IComparable

<source lang="csharp">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) );
  }

}</source>

0
-1

Define your own comparasion type and Comparer

<source lang="csharp">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());
           }
       }
   }</source>

Generic method for IComparable

<source lang="csharp">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."); 
 } 

}</source>

2 is found.
two is found.
MyClass(3) is found.

Implement IComparable

<source lang="csharp">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); 
   } 
 } 

}</source>

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