开发者

Why does comparing my two class return false?

I dont understand. Why does comparing my class return false? I thought .Equals checks if each element are == to eachother and me should be each to me in both classes. So whats the problem and how do i get this to be true?

public class MyTest
{
    string me;
    public MyTest(){}
   开发者_如何学编程 public MyTest(string v) { me = v; }
    public static implicit operator string(MyTest v){return v.me;}
    public static implicit operator MyTest(string v) { return new MyTest(v); }
    public override string ToString(){ return me;}
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("{0}", new MyTest("a").Equals( new MyTest("a")));
        Console.WriteLine("{0}", new MyTest("a") == new MyTest("a"));
        //false, false


Classes are reference types. So, the default 'Equals' method and equality operators, compare the 'references' of the instances (that is, the memory address) in order to verify if 2 instances are equal.

In other words: equality on reference types checks whether the 2 instances are the same instance.

You can override this behaviour, by overriding the Equals and GetHashCode methods. Additionally, you can overload the equality and in-equality operators.

  • GetHashCode method
  • Equals method
  • == operator
  • != operator


You need to override the Equals method because by default, for reference types it compares their references:

public override bool Equals(object obj)
{
    var other = obj as MyTest;
    if (other == null)
    {
        return false;
    }
    return other.me == me;
}

Also when overriding the Equals method it is good practice to override the GetHashCode method as well:

public override int GetHashCode()
{
    return (me ?? string.Empty).GetHashCode();
}


Your class MyTest doesn't actually overload the operator Equals. So on the line where you call

Console.WriteLine("{0}", new MyTest("a").Equals( new MyTest("a")));

that is, by default, just going to do the same thing as ==.

You need to explicitly define equality in your class like this:

public override bool Equals(Object obj)
{
    return (MyTest)obj.me == this.me;
}

that will actually compare the string inside this object to the one inside the other one. Now both calling .Equals and using the == operator will use your defined equality.

Edit: See @Darin Dimitrov's answer for a more comprehensive solution.


You are not comparing two classes but two different instance of class; the test returns false because you are comparing two different references.

You can override this behaviour, overriding Equals and GetHashCode.


You need to override the Equals method on the MyTest class and implement your custom comparison logic in that method. Without that the default implementation will compare only the references.

See this link - Guidelines for Overloading Equals() and Operator == (C# Programming Guide)


struct compares fields by default; class compares references by default. That doesn't mean you should simply make it a struct, as to avoid boxing etc you would also need to override GetHashCode and Equals anyway (plus ToString) - and by the time you've done that, you could have done it for the existing code.

For example:

public static bool operator ==(MyTest x, MyTest y) {
    if(x == null && y == null) return true;
    return x != null && y != null && x.me == y.me;
}
public static bool operator !=(MyTest x, MyTest y) {
    if (x == null && y == null) return false;
    return x == null || y == null || x.me != y.me;
}
public override bool Equals(object obj) {
    MyTest other = obj as MyTest;
    return other != null && other.me == me;
}
public override int GetHashCode() {
    return me == null ? 0 : me.GetHashCode();
}


Equals and '==' for reference types looks if two objects point to the same reference. It doesn´t check the values of the class. You have to override equals (or implement IEquatable) to provide your own logic to compare to instance of a class


You have to override object.Equals (and GetHashCode). If you don't override the default implementation is to return whether they are the same object (and not compare fields).


ehy not use a struct instead (which is a value type and is compared via the sum of the comparisons of its parts

public struct MyTest
{
    string me;
    public MyTest(string v) { me = v; }
    public static implicit operator string(MyTest v) { return v.me; }
    public static implicit operator MyTest(string v) { return new MyTest(v); }
    public override string ToString() { return me; }
}


As far as I know, by default "==" identify if 2 object is the same; and "Equals" compare their values.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜