zoukankan      html  css  js  c++  java
  • 构建可比较的对象(IComparable)

    IComparable接口

      System.IComparable接口指定了一种允许一个对象可基于某些特定键值进行排序的行为。

    namespace System
    {
        [ComVisible(true)]
        public interface IComparable
        {
            int CompareTo(object obj);
        }
    }

    CompareTo()方法背后的逻辑是,根据某个特定数据字段比较传入的对象与当前实例。CompareTo()方法的返回值被用来判断这个类型小于、大于或是等于它所比较的对象。

    • 任何小于0的数字:这个实例在指定对象之前
    • 0:这个实例等于指定对象
    • 任何大于0的数字:这个实例在指定对象之后

    构建可比较对象

      System.Array类定义了一个名为 Sort()的静态方法。在内置类型(int、short、string等)上调用这个方法的时候,可以以数字/字母顺序对数组中的项排序,因为这些内置数据类型实现了IComparable。

    构建可排序的Car类型

    namespace ComparableCar
    {
        class Car : IComparable
        {
            public int CurrentSpeed { get; set; }
            public string PetName { get; set; }
            public int CarID { get; set; }
    public Car() { } public Car( string name, int currSp, int id ) { CurrentSpeed = currSp; PetName = name; CarID = id; }

    int IComparable.CompareTo(object obj) { Car temp = obj as Car; if (temp != null) { if (this.CarID > temp.CarID) return 1; if (this.CarID < temp.CarID) return -1; else return 0; } else throw new ArgumentException("Parameter is not a Car!"); } } }

      由于C#int数据类型(只是CLR System.Int32的简写形式)实现了IComparable,我们就可以按如下所示的方法实现ICompareTo()方法:

            int IComparable.CompareTo( object obj )
            {
                Car temp = obj as Car;
                if (temp != null)
                    return this.CarID.CompareTo(temp.CarID);
                else
                    throw new ArgumentException("Parameter is not a Car!");
            }

      Car类型已经知道如何将它自己和类似对象进行对比:

    namespace ComparableCar
    {
        class Program
        {
            static void Main( string[] args )
            {
                Console.WriteLine("***** Fun with Object Sorting *****
    ");
    Car[] myAutos = new Car[5]; myAutos[0] = new Car("Rusty", 80, 1); myAutos[1] = new Car("Mary", 40, 234); myAutos[2] = new Car("Viper", 40, 34); myAutos[3] = new Car("Mel", 40, 4); myAutos[4] = new Car("Chucky", 40, 5); Console.WriteLine("Here is the unordered set of cars:"); foreach (Car c in myAutos) Console.WriteLine("{0} {1}", c.CarID, c.PetName); Array.Sort(myAutos); Console.WriteLine(); Console.WriteLine("Here is the ordered set of cars:"); foreach (Car c in myAutos) Console.WriteLine("{0} {1}", c.CarID, c.PetName); Console.ReadLine(); } } }

    指定多个排序顺序IComparer

      如果要构建一个既可通过ID排序又可通过昵称排序的Car类型,就需要与另一个标准接口IComparer打交道。

    namespace System.Collections
    {
        [ComVisible(true)]
        public interface IComparer
        {
            int Compare(object x, object y);
        }
    }

       与IComparable接口不同,IComparer接口不是在要排序的类型(即Car)中,而是在许多辅助类中实现的,其中每个排序各有一个依据(如昵称、ID号等)。

    namespace ComparableCar
    {
        //  这个辅助类用来通过昵称排序Car类型的数组
        public class PetNameComparer : IComparer
        {
            // 测试每个对象的昵称
            int IComparer.Compare( object o1, object o2 )
            {
                Car t1 = o1 as Car;
                Car t2 = o2 as Car;
                if (t1 != null && t2 != null)
                    return String.Compare(t1.PetName, t2.PetName);
                else
                    throw new ArgumentException("Parameter is not a Car!");
            }
        }
    }

       System.Array有许多重载的Sort()方法,其中有一个用来在对象上实现IComparer接口。

    namespace ComparableCar
    {
        class Program
        {
            static void Main( string[] args )
            {
                ...
                // 按照昵称进行排序
                Array.Sort(myAutos, new PetNameComparer());
    
                Console.WriteLine("Ordering by pet name:");
                foreach (Car c in myAutos)
                    Console.WriteLine("{0} {1}", c.CarID, c.PetName);
                ...
            }
        }
    }

    自定义属性、自定义排序类型

       值得指出的是,在通过特定数据字段排序Car类型的时候,可以使用自定义的静态属性辅助对象用户。假定Car类型添加了一个静态只读属性SortByPetName,它返回一个实现了IComparer接口的对象的实例(在本例中为PetNameComparer):

    namespace ComparableCar
    {
    // 现在可以使用一个自定义静态属性来返回正确的IComparer接口
    class Car : IComparable {
    ... // 返回SortByPetName比较的属性 public static IComparer SortByPetName { get { return (IComparer)new PetNameComparer(); } }
         ...
    } }

       现在可以使用强关联属性按照昵称排序,而不是只能使用独立的PetNameComparer类型:

    // 简洁明了的按照昵称排序
    Array.Sort(myAutos, Car.SortByPetName);
  • 相关阅读:
    Android Studio 单刷《第一行代码》系列 05 —— Fragment 基础
    Android Studio 单刷《第一行代码》系列 04 —— Activity 相关
    Android Studio 单刷《第一行代码》系列 03 —— Activity 基础
    Android Studio 单刷《第一行代码》系列 02 —— 日志工具 LogCat
    Android Studio 单刷《第一行代码》系列 01 —— 第一战 HelloWorld
    IDEA 内网手动添加oracle,mysql等数据源,以及server returns invalid timezone错误配置
    eclipse maven设置
    IntelliJ IDE 常用配置
    eclipse maven 常见问题解决方案
    Maven 安装和配置
  • 原文地址:https://www.cnblogs.com/gyt-xtt/p/6266043.html
Copyright © 2011-2022 走看看