国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

C#排序比較

2019-11-17 03:18:15
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

C#排序比較

與C#定義了相等性比較規(guī)范一樣,C#也定義了排序比較規(guī)范,以確定一個(gè)對(duì)象與另一個(gè)對(duì)象的先后順序。排序規(guī)范如下

  • IComparable接口(包括IComparable接口和IComparable<T>接口)
  • >和<運(yùn)算符

當(dāng)需要實(shí)現(xiàn)排序算法時(shí),使用IComparable接口。在下面的例子中,Array.Sort靜態(tài)方法可以調(diào)用,是因?yàn)镾ystem.String類(lèi)實(shí)現(xiàn)了IComparable接口。

string[] colors={"Green", "Red", "Blue"};Array.Sort(colors)foreach(string c in colors)    Console.Write(c+ " ");

而<和>運(yùn)算符比較特殊,因?yàn)樗麄円话阌糜诒容^數(shù)字類(lèi)型。因?yàn)榇笥诤托∮谶\(yùn)算符會(huì)被靜態(tài)地解析,因此它們“產(chǎn)生”出高效的代碼,適用于復(fù)雜計(jì)算的場(chǎng)景。

.NET Framework還提供了插件式的排序協(xié)議--IComparer接口。IComparable接口與IComparer接口的差別類(lèi)似與IEquatable和IEqualityComparer接口 (關(guān)于IEqutable接口和IEqualityComparer接口,請(qǐng)參考C#相等性:http://www.survivalescaperooms.com/yang_sy/p/3582946.html)

1. IComparable接口

IComparable接口的定義如下

public interface IComparable    int CompareTo(Object obj);}public interface IComparable<in T>{    int CompareTo(T other);}

這兩個(gè)接口定義了相同的功能。對(duì)于值類(lèi)型,IComparable<T>接口效率高于ICompare接口。上面的兩個(gè)接口的CompareTo方法都按照下面的方式運(yùn)行:

  • 如果a排在b后面,那么a.CompareTo(b)返回1
  • 如果a和不一樣,那么返回0
  • 如果a排在不前面,那么返回-1

我們來(lái)看下面的示例代碼:

IList<Staff> staffs = new List<Staff> {    new Staff{FirstName="AAA", Title="Manager", Dept="Sale"},      new Staff{FirstName="BBB", Title="Accountant", Dept="Finance"},    new Staff{FirstName="CCC", Title="Accountant", Dept="Finance"},};Console.WriteLine("BBB".CompareTo(staffs[0].FirstName)); // 1Console.WriteLine("BBB".CompareTo(staffs[1].FirstName)); // 0Console.WriteLine("BBB".CompareTo(staffs[2].FirstName)); // -1

C#的大部分基本類(lèi)型都實(shí)現(xiàn)了IComparable接口和IComparable<T>接口。很多自定義類(lèi)型同樣也實(shí)現(xiàn)了該接口,這樣便于排序。

IComarable與Equals

假設(shè)一個(gè)類(lèi)型重寫(xiě)了Equals方法并實(shí)現(xiàn)了IComparable接口。那么你肯定希望當(dāng)Equals返回true時(shí),CompareTo應(yīng)當(dāng)返回0。而Equals返回false時(shí),CompareTo可以返回任何值。

換句話(huà)說(shuō),相等性比對(duì)比性更嚴(yán)格;反之則不會(huì)。因此,當(dāng)CompareTo說(shuō)“兩個(gè)對(duì)象相等”時(shí),Equals會(huì)說(shuō)“這兩個(gè)對(duì)象不一定相等”。一個(gè)很好的例子來(lái)自System.String類(lèi)。String.Equals方法和==運(yùn)算符使用序號(hào)排序規(guī)則比較字符串--也就是通過(guò)每個(gè)字符的Unicode的值進(jìn)行排序。而String.CompareTo方法,卻使用不那么嚴(yán)格的基于文化區(qū)域(culture-dependent)進(jìn)行比較。對(duì)于大多數(shù)計(jì)算機(jī),字符ǖ和?,Equals返回False,而CompareTo返回0

你可以實(shí)現(xiàn)通過(guò)IComparer接口,從而完成特定的排序算法。自定義IComparer接口的實(shí)現(xiàn),進(jìn)一步加大了CompareTo和Equals方法之間的差異。比如不區(qū)分大小寫(xiě)的字符串比較器,對(duì)于A和a,將返回0. 這也從反面印證了,ComparTo方法不如Equals方法嚴(yán)格。

2. <和>運(yùn)算符

一些類(lèi)型,定義了<和>運(yùn)算符,比如:

bool after2010 = DateTime.Now > new DateTime(2010, 1, 1);Console.WriteLine(after2010);

當(dāng)實(shí)現(xiàn)<和>運(yùn)算符之后,你需要保證<和>運(yùn)算符與IComparable接口保持一致。這也是.NET Framework的標(biāo)準(zhǔn)。

同樣地,當(dāng)一個(gè)類(lèi)型重載了<和>運(yùn)算符,那么也要求實(shí)現(xiàn)IComparable接口,而反之則不需要。實(shí)際上,大多數(shù).NET類(lèi)型實(shí)現(xiàn)了IComparable接口,并沒(méi)有重載<和>運(yùn)算符。這(排序比較)與相等性比較不一樣:

  • 在實(shí)現(xiàn)相等性比較時(shí),如果重載了Equals方法,那么一般都重載==運(yùn)算符
  • 而在實(shí)現(xiàn)排序性比較時(shí),如果實(shí)現(xiàn)了CompareTo方法,一般不要求重載<運(yùn)算符和>運(yùn)算符

一般地,只有在下面的情形中,才需要重載<運(yùn)算符和>運(yùn)算符:

  • 一個(gè)類(lèi)型本身包含大于和小于這樣的概念
  • 執(zhí)行先后順序比較的方式是唯一的
  • 結(jié)果不會(huì)隨文化區(qū)域(Cultures)變化而變化

System.Stirng類(lèi)型不滿(mǎn)足最后一條,因此string不支持>操作和<操作。因此 “beck” > “Anne”,編譯時(shí)會(huì)拋出錯(cuò)誤。

3. 實(shí)現(xiàn)IComparable接口

下面的實(shí)例代碼中,結(jié)構(gòu)Note表示一個(gè)音樂(lè)的注釋?zhuān)鼘?shí)現(xiàn)了IComparable接口,還重載了<運(yùn)算符和>運(yùn)算符。為了實(shí)例的完整性,我們還重寫(xiě)了Equals和GetHashCode方法,以及重載了==和!=運(yùn)算符,通過(guò)這個(gè)例子,你可以全面的了解排序比較。

internal struct Note : IComparable, IComparable<Note>, IEquatable<Note>{    PRivate int semitonesFromA;    public int SemitonesFromA    {        get { return semitonesFromA; }    }    public Note(int semitonesFromA)    {        this.semitonesFromA = semitonesFromA;    }    // generic IComparable<T>    public int CompareTo(Note other)    {        if (Equals(other))            return 0;        return SemitonesFromA.CompareTo(other.SemitonesFromA);    }    // non-generic IComaparable    public int IComparable.CompareTo(object other)    {        if (!(other is Note))            throw new InvalidOperationException("CompareTo: Not a note");        return CompareTo((Note)other);    }    public static bool operator <(Note n1, Note n2)    {        return n1.CompareTo(n2) < 0;    }    public static bool operator >(Note n1, Note n2)    {        return n1.CompareTo(n2) > 0;    }    // for IEquatable    public bool Equals(Note other)    {        return this.SemitonesFromA == other.SemitonesFromA;    }    // override Object.Equals    public override bool Equals(object other)    {        if (!(other is Note))            throw new InvalidOperationException("CompareTo: Not a note");        return Equals((Note)other);    }    public override int GetHashCode()    {        return SemitonesFromA.GetHashCode();    }    public static bool operator ==(Note n1, Note n2)    {        return n1.Equals(n2);    }    public static bool operator !=(Note n1, Note n2)    {        return !(n1 == n2);    }}

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 和林格尔县| 嘉禾县| 海盐县| 治多县| 凯里市| 天津市| 邯郸市| 黄龙县| 永康市| 昭通市| 吉木乃县| 渭源县| 灵台县| 类乌齐县| 和硕县| 黔江区| 当涂县| 古交市| 五莲县| 金秀| 吉安市| 湾仔区| 四川省| 灌阳县| 西安市| 苍溪县| 通许县| 济阳县| 岳西县| 平山县| 乌拉特后旗| 康定县| 舒兰市| 酒泉市| 石台县| 江口县| 潮州市| 长兴县| 南投县| 确山县| 湘乡市|