簡體   English   中英

在C#中,如何正確重載類中的Equals運算符,以便Queue.Contains()工作?

[英]In C#, how do I overload the Equals operator in my class properly so that Queue.Contains() works?

我創建了一個Class State。 對於狀態對象隊列,我想測試隊列是否已經包含相等值的狀態對象。 當兩個狀態對象均包含一個2D布爾數組時,當兩個數組的所有值相等且順序相同時,它們是相等的。

這是我的相關代碼:

public class State {
   Boolean[,] grid = new Boolean[4,4];

   Public State(Boolean[,] passedGrid){ //Constructor
       grid = Array.Copy(passedGrid, grid, 16);
   }

   public bool Equals(State s2){ //Overloaded equals operator
         for (int x = 0; x < 4; x++){
                 for (int y = 0; y < 4; y++){
                      if (grid[x, y] != s2.grid[x, y]){
                            return false;
                        }
                    }
                }
                return true;
            }

}

    public void testContains(Boolean[] testArray) {
        Queue<State> testQueue = new Queue<State>();
        State s1 = new State(testArray);
        State s2 = new State(testArray);
        testQueue.Enqueue(s1);
        Boolean b = testQueue.Contains(s2);
    }

不幸的是,當調用testContains()並在最后檢查testQueue.Contains(s2)的值時,它仍然表示測試為假,即使它們具有相同的數組值並且Equals運算符也進行了重載進行測試。 我必須做什么或更改才能獲得Queue.Contains可以與我的對象一起使用? 我在某處讀到,當Equals重載時,建議將getHashCode()重載。 在這種情況下,我需要這樣做嗎? 如果是這樣,重載的getHashCode()應該怎么做?

要覆蓋Equals,您需要使用object作為參數類型,並使用關鍵字override

所以你可以嘗試像

    public override bool Equals(object obj)
    {
        return Equals(obj as State);
    }
    public bool Equals(State s2)
    { //Overloaded equals operator 
        for (int x = 0; x < 4; x++)
        {
            for (int y = 0; y < 4; y++)
            {
                if (grid[x, y] != s2.grid[x, y])
                {
                    return false;
                }
            }
        }
        return true;
    }

您可能還應該包括null測試

看看Equals()和運算符==重載的准則(C#編程指南)

您應該override Equals

public override bool Equals(object s2)
{
    //implementation
}

為了更好的實踐,您應該實現一些其他接口,例如: IEquatable IEqualtable<State>和方法GetHashCode IEquatable IEqualtable<T>的重寫Equals方法和Equals方法可以共享一個通用的私有Equals方法。

您缺少覆蓋關鍵字

   public override bool Equals(Object obj) {
       // fill in the body
    }

您只需要重寫在Object類上定義的虛擬方法:

public override Equals(object other)
{
   if(other is State)
        return Equals((State)other); 
   return base.Equals(other);
}

您需要使用此泛型重載,因為此方法由Contains方法使用,僅添加具有相同名稱的實例方法是不夠的。

請在下面找到適合您的代碼:

    public class State : Object {
   Boolean[,] grid = new Boolean[4,4];

   public State(Boolean[,] passedGrid){ //Constructor
       Array.Copy(passedGrid, grid, 16);
   }

   public override bool Equals(Object s2){ //Overloaded equals operator
         for (int x = 0; x < 4; x++){
                 for (int y = 0; y < 4; y++){
                      if (grid[x, y] != ((State)s2).grid[x, y]){
                            return false;
                        }
                    }
                }
                return true;
            }

}


    class Program
    {
        Boolean[,] testArray = new Boolean[4, 4];

        public static void Main()
        {
            Program p = new Program();
            p.testContains(p.testArray);
        }

        public void testContains(Boolean[,] testArray)
        {
            Queue<State> testQueue = new Queue<State>();
            State s1 = new State(testArray);
            State s2 = new State(testArray);
            testQueue.Enqueue(s1);
            Boolean b = testQueue.Contains(s2);
            //b is true here
        }

    }
}

另外,請查看下面的鏈接以獲得覆蓋Equals方法的准則:

http://msdn.microsoft.com/zh-CN/library/ms173147(v=vs.80).aspx

對於定義自定義相等關系的類類型,應遵循以下規定:

  1. 該類應該是不可變的,並且不能封裝可變狀態。 當且僅當此類引用僅用於封裝此類對象的“標識”或其不可變屬性時,不可變類才可以保留對可變對象的引用。
  2. 該類必須重寫`bool Equals(Object Other)`,以便當“ Other”是該類的等效實例時(一個實例等同於它自己;對於可變類型,一個實例是* only *)返回“ true”。等同於自身)。
  3. 該類必須重寫int GetHashCode(),以便任何兩個等效的實例將返回相同的值,並且最好使兩個任意選擇的非等效的實例將不太可能返回相同的值。
  4. 如果該類是密封的,則除執行上述操作外,還可以為其自身的類型實現“ IEquatable”。 未密封的類不應實現“ IEquatable”。

關於您的特定類,我建議由於僅有65,536個可能的不同實例,因此您應該簡單地存儲一個Integer ,該Integer標識使用的是哪種位組合,在Equals進行比較,然后將其返回給GetHashCode

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM