本分步指南描述如何使用两个接口: IComparerIComparable。在同一篇文章中讨论这些接口有两个原因。经常在一起,使用这些接口和接口类似 (并且有相似的名称),尽管它们用于不同用途。

如果您有一个数组的类型 (如字符串整数) 已经在支持IComparer,可以该数组进行排序而不提供对IComparer的任何显式引用。在这种情况下,数组中的元素强制转换为IComparer (Comparer.Default) 为您的默认实现。但是,如果您想要为您自定义的对象提供排序或比较功能,则必须实现一个或这两种接口。

在这篇文章中引用以下.NET Framework 类库命名空间:

System.Collections

IComparable

IComparable的角色是提供方法可以比较两个对象的特定类型。这是有必要的如果您想要提供的对象的任何排序功能。将IComparable视为提供您的对象的默认排序顺序。例如,如果具有您的类型的对象的数组,则调用该阵列上的排序方法IComparable排序过程提供的比较结果的对象。实现IComparable接口时,必须实现CompareTo方法中,按如下所述:

// Implement IComparable CompareTo method - provide default sort order.
int IComparable.CompareTo(object obj)
{
car c=(car)obj;
return String.Compare(this.make,c.make); }

在方法的比较是根据数据类型的值进行比较的不同。在此示例中使用String.Compare是因为选择用于比较的属性是一个字符串。

IComparer

IComparer的角色是提供其它比较机制。例如,您可以提供对多个字段或属性,您的类的排序升序和降序顺序对相同的字段,或者这两者。

使用IComparer是一个两步过程。首先,声明实现IComparer,一个类,然后实现比较方法:

private class sortYearAscendingHelper : IComparer
{
int IComparer.Compare(object a, object b)
{
car c1=(car)a;
car c2=(car)b;
if (c1.year > c2.year)
return 1;
if (c1.year < c2.year)
return -1;
else
return 0;
}
}

请注意IComparer.Compare方法需要第三级进行比较。根据大于、 等于还是小于另一个值是否返回 1,0,则为-1。通过使用此方法切换逻辑运算符,可以更改排序顺序 (升序或降序)。

第二步是声明一个返回 IComparer 对象的实例的方法:

public static IComparer sortYearAscending()
{
return (IComparer) new sortYearAscendingHelper();
}

在此的示例为第二个参数时,调用重载的 Array.Sort 方法接受 IComparer 使用对象。IComparer 的使用并不限于数组。它将被接受作为许多不同的集合和控件类中的参数。

分步示例

下面的示例演示如何使用这些接口。为了演示 IComparer 和 IComparable,创建一个名为 汽车 的类。汽车 对象都有 使 和 属性。升序排序将 使 该字段启用通过 IComparable 接口和按降序排序在 使 该字段启用通过 IComparer 界面。为通过IComparer 使用的 年份 属性提供了既升序和降序排序。

  1. 在 Visual C#,创建新的控制台应用程序项目。命名应用程序 ConsoleEnum。
  2. 重命名为 Host.cs,Program.cs 然后将代码替换下面的代码。

    注意在 Visual Studio.net 2003 年重命名为 Host.cs Class1.cs

    using System;
    
    namespace ConsoleEnum
    {
    class host
    {
    [STAThread]
    static void Main(string[] args)
    {
    // Create an arary of car objects.
    car[] arrayOfCars= new car[6]
    {
    new car("Ford",1992),
    new car("Fiat",1988),
    new car("Buick",1932),
    new car("Ford",1932),
    new car("Dodge",1999),
    new car("Honda",1977)
    }; // Write out a header for the output.
    Console.WriteLine("Array - Unsorted\n"); foreach(car c in arrayOfCars)
    Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo IComparable by sorting array with "default" sort order.
    Array.Sort(arrayOfCars);
    Console.WriteLine("\nArray - Sorted by Make (Ascending - IComparable)\n"); foreach(car c in arrayOfCars)
    Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo ascending sort of numeric value with IComparer.
    Array.Sort(arrayOfCars,car.sortYearAscending());
    Console.WriteLine("\nArray - Sorted by Year (Ascending - IComparer)\n"); foreach(car c in arrayOfCars)
    Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo descending sort of string value with IComparer.
    Array.Sort(arrayOfCars,car.sortMakeDescending());
    Console.WriteLine("\nArray - Sorted by Make (Descending - IComparer)\n"); foreach(car c in arrayOfCars)
    Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo descending sort of numeric value using IComparer.
    Array.Sort(arrayOfCars,car.sortYearDescending());
    Console.WriteLine("\nArray - Sorted by Year (Descending - IComparer)\n"); foreach(car c in arrayOfCars)
    Console.WriteLine(c.Make + "\t\t" + c.Year); Console.ReadLine();
    }
    }
    }
  3. 将类添加到项目中。命名类 汽车
  4. 用下列替换代码中 Car.cs:
    using System;
    using System.Collections;
    namespace ConsoleEnum
    {
    public class car : IComparable
    {
    // Beginning of nested classes. // Nested class to do ascending sort on year property.
    private class sortYearAscendingHelper: IComparer
    {
    int IComparer.Compare(object a, object b)
    {
    car c1=(car)a;
    car c2=(car)b; if (c1.year > c2.year)
    return 1; if (c1.year < c2.year)
    return -1; else
    return 0;
    }
    } // Nested class to do descending sort on year property.
    private class sortYearDescendingHelper: IComparer
    {
    int IComparer.Compare(object a, object b)
    {
    car c1=(car)a;
    car c2=(car)b; if (c1.year < c2.year)
    return 1; if (c1.year > c2.year)
    return -1; else
    return 0;
    }
    } // Nested class to do descending sort on make property.
    private class sortMakeDescendingHelper: IComparer
    {
    int IComparer.Compare(object a, object b)
    {
    car c1=(car)a;
    car c2=(car)b;
    return String.Compare(c2.make,c1.make);
    }
    } // End of nested classes. private int year;
    private string make; public car(string Make,int Year)
    {
    make=Make;
    year=Year;
    } public int Year
    {
    get {return year;}
    set {year=value;}
    } public string Make
    {
    get {return make;}
    set {make=value;}
    } // Implement IComparable CompareTo to provide default sort order.
    int IComparable.CompareTo(object obj)
    {
    car c=(car)obj;
    return String.Compare(this.make,c.make);
    } // Method to return IComparer object for sort helper.
    public static IComparer sortYearAscending()
    {
    return (IComparer) new sortYearAscendingHelper();
    } // Method to return IComparer object for sort helper.
    public static IComparer sortYearDescending()
    {
    return (IComparer) new sortYearDescendingHelper();
    } // Method to return IComparer object for sort helper.
    public static IComparer sortMakeDescending()
    {
    return (IComparer) new sortMakeDescendingHelper();
    } }
    }
  5. 运行该项目。 在控制台窗口中将显示以下输出:
    Array - Unsorted
    
    Ford            1992
    Fiat 1988
    Buick 1932
    Ford 1932
    Dodge 1999
    Honda 1977 Array - Sorted by Make (Ascending - IComparable) Buick 1932
    Dodge 1999
    Fiat 1988
    Ford 1932
    Ford 1992
    Honda 1977 Array - Sorted by Year (Ascending - IComparer) Ford 1932
    Buick 1932
    Honda 1977
    Fiat 1988
    Ford 1992
    Dodge 1999 Array - Sorted by Make (Descending - IComparer) Honda 1977
    Ford 1932
    Ford 1992
    Fiat 1988
    Dodge 1999
    Buick 1932 Array - Sorted by Year (Descending - IComparer) Dodge 1999
    Ford 1992
    Fiat 1988
    Honda 1977
    Buick 1932
    Ford 1932

转载自:http://support.microsoft.com/kb/320727

C#中如何使用IComparable<T>与IComparer<T>接口(转载)的更多相关文章

  1. 对象的比较与排序(三):实现IComparable<T>和IComparer<T>泛型接口

    来源:http://www.cnblogs.com/eagle1986/archive/2011/12/06/2278531.html 1:比较和排序的概念 比较:两个实体类之间按>,=,< ...

  2. IComparer<T> 接口Linq比较接口

    IComparer<T>比较两个对象并返回一个值,指示一个对象是小于.等于还是大于另一个对象. 在Linq当中,很多扩展方法接受一个实现IComparer<T>接口的实例的对象 ...

  3. oracle中函数和存储过程的区别和联系【转载竹沥半夏】

    oracle中函数和存储过程的区别和联系[转载竹沥半夏] 在oracle中,函数和存储过程是经常使用到的,他们的语法中有很多相似的地方,但也有自己的特点.刚学完函数和存储过程,下面来和大家分享一下自己 ...

  4. Function接口 – Java8中java.util.function包下的函数式接口

    Introduction to Functional Interfaces – A concept recreated in Java 8 Any java developer around the ...

  5. 解决VS2010中winsock.h与winsock2.h冲突(重复定义)——转载

    解决VS2010中winsock.h与winsock2.h冲突(重复定义)——转载 当这两个头文件顺序颠倒时,编译会出现许多莫名其妙的错误,错误如下: 1>…\include\ws2def.h( ...

  6. 微信小程序红包开发 小程序发红包 开发过程中遇到的坑 微信小程序红包接口的

    微信小程序红包开发 小程序发红包 开发过程中遇到的坑 微信小程序红包接口的   最近公司在开发一个小程序红包系统,客户抢到红包需要提现.也就是通过小程序来给用户发红包. 小程序如何来发红包呢?于是我想 ...

  7. 关于Java中的对象、类、抽象类、接口、继承之间的联系

    关于Java中的对象.类.抽象类.接口.继承之间的联系: 导读: 寒假学习JavaSE基础,其中的概念属实比较多,关联性也比较大,再次将相关的知识点复习一些,并理顺其中的关系. 正文: 举个例子:如果 ...

  8. Java中的函数式编程(二)函数式接口Functional Interface

    写在前面 前面说过,判断一门语言是否支持函数式编程,一个重要的判断标准就是:它是否将函数看做是"第一等公民(first-class citizens)".函数是"第一等公 ...

  9. IComparable<T> Vs. IComparer<T> System.Comparison<T>

    Well they are not quite the same thing as IComparer<T> is implemented on a type that is capabl ...

随机推荐

  1. Apache下的FileUtils.listFiles方法简单使用技巧

    一.引言 Apache提供的很多工具方法非常好用,推荐. 今天在使用的过程中使用到了org.apache.commons.io.FileUtils.listFiles方法,本文主要谈谈这个工具方法的用 ...

  2. HTML之禁止输入文本

    一个文本框,禁止输入文本有2个方式,一个是利用readonly ,一个是利用 disabled. 那么两者虽然目的都可以达到,但是从表现上来看disabled会显得更加的直观,为什么这么说. 请看截图 ...

  3. webapp之路--百度手机前端经验(转)

    看了之后收获很大,分享一下: 本文将围绕我半年来在移动前端工程化做的一些工作做的总结,主要从localstorage缓存和版本号管理,模块化,静态资源渲染方式三个方面总结手机百度前端一年内沉淀的解决方 ...

  4. Linux:系统的基本优化

    前言,在拥有一台服务器的时候,首先第一件事就要根据自己的需求进行初期的优化(装好系统了),以下是关于linux系统的基本优化,内容来源与网络,自己整理了以下,忘记来自哪个网址了, centos 系统优 ...

  5. javactript关闭窗体,刷新父窗体

    //关闭,父窗口弹出对话框,子窗口直接关闭this.Response.Write("<script language=javascript>window.close();< ...

  6. egret dragonbones部件替换产生位移的解决方案

    原理:使用Armature.getSlot("urpart").display.texture去替换骨骼纹理即可需要:1 骨骼动画导出的时候不要裁剪部件的透明区域,在导出设置里面设 ...

  7. 织梦系统与discuz论坛整合方法

    如何完成dedecms模板系统与discuz论坛整合呢? 这里的整合指会员信息,会员登陆.退出的同步:论坛信息的引用:等等. 首先,我们先来安装织梦(dedecms)系统. 然后,我们在网站根目录下建 ...

  8. jQuery插件实现的方法和原理简单说明

    下文来自 http://www.itzhai.com/jquery-plug-ins-to-achieve-the-methods-and-principles-of-simple-instructi ...

  9. SQL SERVER 2008 Hierarchyid数据类型

    以往我们在关系数据库中建立树状结构的时候,通常使用ID+ParentID来实现两条纪录间的父子关系.但这种方式只能标示其相对位置.解决这类问题在SqlServer2005出现之前通常是采用游标来操作, ...

  10. 使用for循环输出空心的菱形的思路-还是没有办法理解

    之前已经成功写过一次代码,今天重新看这个题目时,一下子又没了思路,在草稿纸上比划了大概十分钟才想到实现的思路.思路跟上次实现的完全一样,发现时间长了就忘记了!真是好记性不如烂笔头,何况我这么差的记性呢 ...