詳解C# IComparable和IComparer接口和自定義比較器
前言
ArrayList里面有一個方法:
public virtual void Sort(IComparer comparer); 使用指定的比較器對整個 System.Collections.ArrayList 中的元素進(jìn)行排序。 comparer:比較元素時要使用的 System.Collections.IComparer 實(shí)現(xiàn)。
啥玩意???
1.Comparer類簡單介紹
想弄清楚這個,我們先來看看這么一個類。
在System.Collections名稱空間中,有這么一個類:Comparer。顧名思義,他可以實(shí)現(xiàn)對簡單類型的比較,什么意思呢?來看如下代碼:
int a=1,b=2;
正常情況下,我們要怎樣比較他們的大小?if,運(yùn)算符,……?這當(dāng)然可以,不過Comparer已經(jīng)給我們提供了一個函數(shù),可以直接使用:(需要using System.Collections;)
Console.WriteLine(Comparer.Default.Compare(a,b));
因?yàn)閍<b,所以控制臺會輸出-1。(這個函數(shù)總是返回-1,0,1三個值。)
這里通過Comparer里的靜態(tài)屬性Default獲得Comparer的實(shí)例調(diào)用了Comparer里的非靜態(tài)函數(shù)Compare。
(還可以比較根據(jù)字母比較兩個string類型,這里就省略介紹了)
2.自定義比較器,IComparable,IComparer接口
當(dāng)然,這個類不僅僅只是用來比較兩個數(shù)的大小的。有時候我們想直接比較兩個對象,但是引用里面的屬性或許比較麻煩。尤其是參考要素過多,不好直接比較的時候,怎樣才能更高效地比較兩個對象呢?這時候,我們就需要自定義比較器了。
首先來介紹IComparable接口。這個接口里只有一個方法CompareTo()。讓你的類實(shí)現(xiàn)這個接口的CompareTo方法,就可以直接調(diào)用這個方法和另一個對象比較。下面是例子:
public class ClassTest : IComparable
{
public int intTest;
public int CompareTo(object obj)
{
return intTest-((ClassTest)obj).intTest;
//這里的代碼可以按需要自己編寫,這里只是一個簡單的示例
}
}
然后就可以直接使用啦:
ClassTest a = new ClassTest(){intTest=1};
ClassTest b = new ClassTest(){intTest=2};
Console.WriteLine(a.CompareTo(b));//輸出-1
Comparer類已經(jīng)為我們提供了IComparer的默認(rèn)實(shí)現(xiàn),但我們?nèi)匀豢梢宰远x它。新建一個類:(記得using System.Collections;)
public class ClassTestComparer : IComparer
{
public static IComparer Default = new ClassTestComparer();
//這里必須使用這樣的定義,將對象轉(zhuǎn)化為IComparer類型有很大用處,下面會介紹
public int Compare(object a,object b)
{
return ((ClassTest)a).intTest - ((ClassTest)b).intTest;
//同樣這里使用最簡單的示例,但是你可以大放異彩
}
}
注意,如果用于比較的類和設(shè)定的類不一樣,就會出現(xiàn)錯誤。
使用示例:
ClassTest a = new ClassTest(){intTest=1};
ClassTest b = new ClassTest(){intTest=2};
Console.WriteLine(ClassTestComparer.Default.Compare(a,b));
//結(jié)果是-1
可以發(fā)現(xiàn),這兩個接口的不同之處在于:IComparable在要比較的對象的類中實(shí)現(xiàn),可以比較該對象和另一個對象。IComparer在一個單獨(dú)的類中實(shí)現(xiàn),可以比較任意兩個對象(關(guān)鍵是你的設(shè)置)。
3.對集合排序
當(dāng)然,這兩個接口還有更強(qiáng)大的用處。我們可以使用這兩個接口對集合進(jìn)行排序。還記得前言里的Sort()方法嗎?接下來就以ArrayList為例,介紹如何使用。
ArrayList ClassTests = new ArrayList();
ClassTest a = new ClassTest(){intTest=1};
ClassTest b = new ClassTest(){intTest=2};
ClassTest c = new ClassTest(){intTest=3};
ClassTests.Add(a);
ClassTests.Add(b);
ClassTests.Add(c);
ClassTests.Sort();
//使用無參的Sort,將調(diào)用類中的CompareTo()方法,因?yàn)镃lassTest實(shí)現(xiàn)了這個方法,所以是可以調(diào)用的。如果沒有實(shí)現(xiàn),編譯器會報(bào)錯。
ClassTests.Sort(ClassTestComparer.Default);
//這將使用Compare()方法對集合中的元素排序。ClassTestComparer類實(shí)現(xiàn)了這個方法,并且提供了一個IComparer類型的屬性。
需要注意的是:
- 兩個接口提供的方法返回值都是int類型的,負(fù)數(shù)代表小于,0代表等于,正數(shù)代表大于。所以對數(shù)字之外的自定義比較器,需要人工設(shè)定什么是“大”,什么是“小”。所以上文示例中兩個數(shù)直接相減,就可以比較大小。
- 排序完之后,按照返回的int值,集合是由小到大排列的。
- 使用無參Sort()時,集合中至少要有一個類實(shí)現(xiàn)了IComparable,否則會報(bào)錯。
- 一般來說,都是對同一個類進(jìn)行比較。不過,也可以實(shí)現(xiàn)對不同類比較的代碼,這就看具體需要了。
到此這篇關(guān)于詳解C# IComparable和IComparer接口和自定義比較器的文章就介紹到這了,更多相關(guān)C# IComparable IComparer內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實(shí)現(xiàn)拷貝文件的9種方法小結(jié)
最近遇一個問題,一個程序調(diào)用另一個程序的文件,結(jié)果另一個程序的文件被占用,使用不了文件,這時候的解決方案就是把另一個程序的文件拷貝到當(dāng)前程序就可以了,本文介紹用C#拷貝文件的多種方式,需要的朋友可以參考下2024-04-04
c# 通過內(nèi)存映射實(shí)現(xiàn)文件共享內(nèi)存的示例代碼
這篇文章主要介紹了c# 通過內(nèi)存映射實(shí)現(xiàn)文件共享內(nèi)存的示例代碼,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-04-04
C#實(shí)現(xiàn)將RTF文檔轉(zhuǎn)換為圖片(PNG,JPG)
RTF(Rich?Text?Format)作為跨平臺兼容的富文本格式,在文檔交互、內(nèi)容存儲場景中應(yīng)用廣泛,下面我們來看看如何使用C#實(shí)現(xiàn)將?RTF?轉(zhuǎn)換為?PNG、JPG?等圖片格式吧2025-12-12
使用C#創(chuàng)建、修改和刪除Word文檔中的VBA宏
在處理 Word 文檔時,VBA宏成為自動化任務(wù)的強(qiáng)大工具,它允許用戶通過編程實(shí)現(xiàn)文檔中的重復(fù)性操作,節(jié)省時間并減少人為錯誤,當(dāng)文檔中的 VBA 宏比較多時,手動操作會非常繁瑣,因此本文將詳細(xì)介紹如何在 C# 中操作 Word 文檔中的 VBA 宏,需要的朋友可以參考下2026-02-02
C#中String.LastIndexOf方法小結(jié)
String.LastIndexOf()是C#中string類的一個方法,它用于在字符串中查找指定子字符串(或字符)最后一次出現(xiàn)的位置,并返回其索引,本文主要介紹了C#中String.LastIndexOf方法小結(jié),感興趣的可以了解一下2024-01-01
淺拷貝和深拷貝深入理解(shallow copy VS deep copy)
淺拷貝和深拷貝深入理解(shallow copy VS deep copy) 本文重點(diǎn)討論引用類型變量的拷貝機(jī)制和實(shí)現(xiàn)2014-01-01
C#中Decimal類型截取保留N位小數(shù)并且不進(jìn)行四舍五入操作
這篇文章主要介紹了C#中Decimal類型截取保留N位小數(shù)并且不進(jìn)行四舍五入操作,本文給出需求說明和實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-06-06

