上午,有位初學者朋友問:如何比較兩個字節數組中各字節是否相等?
不許笑,我一向反對嘲笑初學者,初學者不認真學習時你可以批評,但不能譏嘲。你不妨想想,你自己開始學習編程的時候又是什么個光景?
好,於是,這位初學者朋友就做了以下嘗試:
byte[] buffer1 = { 0x001, 0x002, 0x003 }; byte[] buffer2 = { 0x001, 0x002, 0x003 }; Console.WriteLine(buffer1 == buffer2);
想一下,這個方法行嗎?結果一運行,這位朋友差點暈倒,呵呵。buffer1 == buffer2比較的是這兩個byte[]實例,不會去比較里面的元素。
這位朋友吸取教訓后,把代碼作如下修改:
byte[] buffer1 = { 0x001, 0x002, 0x003 }; byte[] buffer2 = { 0x001, 0x002, 0x003 }; bool isEq = false; if (buffer1.Length != buffer2.Length) { isEq = false; } else { isEq = true; for (int i = 0; i < buffer1.Length; i++) { if (buffer1[i] != buffer2[i]) { isEq = false; break; } } } Console.WriteLine(isEq);
這一次有效果了,來,為這位朋友所取得的成就鼓掌。
到了此處,大概是可以了結了,可是這位朋友很執着,他繼續問:“有沒有更簡單一些的方法?”
我不回答,於是,他又動起腦子,不久,又寫出一段代碼:
public static class ByteArrayExt { public static bool IsEqual(this byte[] src, byte[] dis) { bool isEq = false; if (src.Length != dis.Length) { isEq = false; } else { isEq = true; for (int i = 0; i < src.Length; i++) { if (src[i] != dis[i]) { isEq = false; break; } } } return isEq; } }
他把剛才的代碼就寫到擴展方法中,擴展對象是byte[]類型。以后只要遇到這種情況就不必每次都寫那么多代碼,直接調用擴展方法就可以了。
Console.WriteLine(buffer1.IsEqual(buffer2));
不錯,看來這位同學悟性挺高,懂得發揮擴展方法的作用了。但是,這位兄台仍舊不滿意,還不夠簡單。
其實,.NET類庫已經有一個現成的方法了,也是擴展方法,要比較兩個序列(如數組,列表等)中各個元素是否相等,只要調用該方法即可,不用自己寫代碼實現。什么方法呢?這個方法的芳名叫做SequenceEqual。
因此,整個程序的代碼我們完全可以很簡單地完成。
byte[] buffer1 = { 0x001, 0x002, 0x003 }; byte[] buffer2 = { 0x001, 0x002, 0x003 }; Console.WriteLine(buffer1.SequenceEqual(buffer2));
這位仁兄如獲至寶,馬上興奮起來,啊!原來還可以這樣耍!就好比孫行者在龍宮發現如意棍一樣的興奮。
可能有些朋友又會問了,如果我們比較的元素是自己編寫的類呢?我需要自己的比較規則。無妨,SequenceEqual方法還有一個重載,就是可以向方法的參數傳一個實現了IEqualityComparer<in T>接口的對象。
由於EqualityComparer<T>類實現了該接口,在我自自定義比較器時,可以直接從該類派生。
比如我們定義了一個“帥哥”類,它包含Name和ID兩個屬性,對於任意兩個“帥哥”對象,只要ID相等,我們就認為他們是同一位帥哥。
public class 帥哥 { public int ID { get; set; } public string Name { get; set; } }
然后,我們定義一個比較器,專門用於判斷兩位帥哥是否為同一位帥哥。
public class 帥哥EqualityComparer : EqualityComparer<帥哥> { public override bool Equals(帥哥 x, 帥哥 y) { if (x.ID == y.ID) { return true; } return false; } public override int GetHashCode(帥哥 obj) { return obj.ID.GetHashCode(); } }
來,開始做測試吧。
帥哥[] sgarr1 = { new 帥哥 { ID = 1, Name = "小李" }, new 帥哥 { ID = 2, Name = "小劉" }, new 帥哥 { ID = 3, Name = "小王" } }; 帥哥[] sgarr2 = { new 帥哥 { ID = 1, Name = "小李" }, new 帥哥 { ID = 2, Name = "小劉" }, new 帥哥 { ID = 3, Name = "小王" } }; 帥哥[] sgarr3 = { new 帥哥 { ID = 7, Name = "小張" }, new 帥哥 { ID = 8, Name = "小黃" }, new 帥哥 { ID = 5, Name = "小胡" } }; // 實例化比較器 帥哥EqualityComparer comparer = new 帥哥EqualityComparer(); Console.WriteLine(sgarr1.SequenceEqual(sgarr2, comparer)); Console.WriteLine(sgarr2.SequenceEqual(sgarr3, comparer));
至此,相信這位仁兄已經不亦樂乎了。
總結:我們平時做項目寫程序都應該向這位仁兄學習,努力尋找最簡單最高效的方法去處理問題。