繁体   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