【.net】從比較兩個字節數組談起


上午,有位初學者朋友問:如何比較兩個字節數組中各字節是否相等?

不許笑,我一向反對嘲笑初學者,初學者不認真學習時你可以批評,但不能譏嘲。你不妨想想,你自己開始學習編程的時候又是什么個光景?

好,於是,這位初學者朋友就做了以下嘗試:

            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));

至此,相信這位仁兄已經不亦樂乎了。

總結:我們平時做項目寫程序都應該向這位仁兄學習,努力尋找最簡單最高效的方法去處理問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM