4

クラス State を作成しました。State オブジェクトの Queue の場合、Queue に同じ値の State オブジェクトが既に含まれているかどうかをテストしたいと考えています。それぞれが 2D ブール配列を含む 2 つの State オブジェクトは、配列のすべての値が等しく、同じ順序である場合に等しくなります。

これが私の関連コードです:

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 演算子がオーバーロードされているにもかかわらず、テストが false であると表示されます。オブジェクトで Queue.Contains を機能させるには、何を行うか、または変更する必要がありますか? Equals がオーバーロードされるたびに getHashCode() をオーバーロードすることが推奨されていることをどこかで読みました。この場合、私はそれをする必要がありますか?もしそうなら、オーバーロードされた getHashCode() は何をすべきでしょうか?

4

6 に答える 6

2

Equals をオーバーライドするにobjectは、パラメーター type とキーワードとしてを使用する必要があります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;
    }

おそらく test for も含める必要がありますnull

Equals() および演算子 == のオーバーロードに関するガイドライン (C# プログラミング ガイド) を参照してください。

于 2012-10-10T05:32:01.457 に答える
0

あなたはoverride 等しいはずです。

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

より良い実践のために、次のような他のインターフェースを実装する必要がありIEquatable IEqualtable<State>ますGetHashCode。オーバーライドEqualsメソッドと のEqualsメソッドはIEquatable IEqualtable<T>、共通のプライベートEqualsメソッドを共有できます。

于 2012-10-10T05:30:11.147 に答える
0

オーバーライド キーワードがありません

   public override bool Equals(Object obj) {
       // fill in the body
    }
于 2012-10-10T05:30:39.620 に答える
0

class で定義された仮想メソッドをオーバーライドするだけですObject:

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

Containsこのメソッドはメソッドによって使用され、同じ名前のインスタンス メソッドを追加するだけでは十分でないため、このジェネリック オーバーロードを使用する必要があります。

于 2012-10-10T05:32:04.793 に答える
0

カスタム等値関係を定義するクラス タイプの場合、次のことが適用されます。

  1. クラスは不変である必要があり、可変状態をカプセル化してはなりません。不変クラスが可変オブジェクトへの参照を保持することは、そのような参照がそのようなオブジェクトの *アイデンティティ* またはその不変属性をカプセル化するためにのみ使用される場合にのみ許容されます。
  2. クラスは、`Other` がクラスの等価インスタンスである場合に `true` を返すように `bool Equals(Object Other)` をオーバーライドする必要があります (インスタンスはそれ自体と等価です。可変型の場合、インスタンスは *唯一* のものです)。それはそれ自体と同等です)。
  3. クラスは、2 つの同等のインスタンスが同じ値を返すように「int GetHashCode()」をオーバーライドする必要があります。これにより、任意に選択された 2 つの同等でないインスタンスが同じ値を返す可能性が低くなります。
  4. クラスが封印されている場合、上記に加えて、独自の型に「IEquatable」を実装する場合があります。封印されていないクラスは、「IEquatable」を実装すべきではありません。

特定のクラスに関しては、65,536 個の異なるインスタンスしか考えられないため、Integerどのビットの組み合わせが使用されているかを識別する を単純に保存し、それを で比較しEquals、 で返すことをお勧めしますGetHashCode

于 2012-10-10T23:56:26.507 に答える
0

以下のコードを見つけてください。これはうまく機能します。

    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/en-us/library/ms173147(v=vs.80).aspx

于 2012-10-10T05:33:11.670 に答える