Почему сравнение двух моих классов возвращает false?

c#

264 просмотра

10 ответа

Я не понимаю Почему сравнение моего класса возвращает false? Я думал .Equals проверяет, каждый ли элемент == друг к другу, и я должен быть каждый для меня в обоих классах. Так в чем же проблема и как я могу получить это, чтобы быть правдой?

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
Источник Размещён: 12.11.2019 09:34

Ответы (10)


14 плюса

Решение

Классы являются ссылочными типами. Таким образом, метод Equals по умолчанию и операторы равенства сравнивают «ссылки» экземпляров (то есть адрес памяти), чтобы проверить, равны ли 2 экземпляра.

Другими словами: равенство в ссылочных типах проверяет, являются ли 2 экземпляра одинаковыми.

Вы можете переопределить это поведение, переопределив методы Equals и GetHashCode. Кроме того, вы можете перегрузить операторы равенства и равенства.

Автор: Frederik Gheysels Размещён: 06.12.2010 08:17

6 плюса

Вам необходимо переопределить метод Equals, потому что по умолчанию для ссылочных типов он сравнивает их ссылки:

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

Также при переопределении метода Equals рекомендуется также переопределить метод GetHashCode :

public override int GetHashCode()
{
    return (me ?? string.Empty).GetHashCode();
}
Автор: Darin Dimitrov Размещён: 06.12.2010 08:18

1 плюс

Ваш класс на MyTestсамом деле не перегружает оператора Equals. Так на линии, где вы звоните

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

то есть, по умолчанию, я собираюсь сделать то же самое, что и ==.

Вам нужно явно определить равенство в вашем классе следующим образом:

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

это фактически сравнит строку внутри этого объекта с той, что внутри другого. Теперь и вызов, .Equalsи использование ==оператора будут использовать ваше определенное равенство.

Изменить : см. Ответ @ Darin Dimitrov для более полного решения.

Автор: mgiuca Размещён: 06.12.2010 08:20

1 плюс

Вы сравниваете не два класса, а два разных экземпляра класса; тест возвращает false, потому что вы сравниваете две разные ссылки.

Вы можете переопределить это поведение, переопределив Equalsи GetHashCode.

Автор: systempuntoout Размещён: 06.12.2010 08:20

1 плюс

Вам необходимо переопределить Equalsметод в MyTestклассе и реализовать свою собственную логику сравнения в этом методе. Без этого реализация по умолчанию будет сравнивать только ссылки.

Смотрите эту ссылку - Руководство по перегрузке Equals () и Operator == (Руководство по программированию в C #)

Автор: Unmesh Kondolikar Размещён: 06.12.2010 08:18

1 плюс

structсравнивает поля по умолчанию; classсравнивает ссылки по умолчанию. Это не означает, что вы должны просто сделать это struct, поскольку, чтобы избежать упаковки и т. Д., Вам также необходимо переопределить GetHashCodeи в Equals любом случае (плюс ToString) - и к тому времени, когда вы это сделаете, вы могли бы сделать это для существующего кода.

Например:

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();
}
Автор: Marc Gravell Размещён: 06.12.2010 08:25

0 плюса

Равно и '==' для ссылочных типов выглядит, если два объекта указывают на одну и ту же ссылку. Он не проверяет значения класса. Вы должны переопределить equals (или реализовать IEquatable), чтобы предоставить свою собственную логику для сравнения с экземпляром класса

Автор: Jehof Размещён: 06.12.2010 08:17

0 плюса

Вы должны переопределить object.EqualsGetHashCode). Если вы не переопределите реализацию по умолчанию, нужно вернуть, являются ли они одним и тем же объектом (а не сравнивать поля).

Автор: Motti Размещён: 06.12.2010 08:17

0 плюса

Вместо этого не следует использовать структуру (которая является типом значения и сравнивается посредством суммы сравнений ее частей.

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; }
}
Автор: Dean Chalk Размещён: 06.12.2010 08:19

-2 плюса

Насколько я знаю, по умолчанию "==" идентифицируют, если 2 объекта одинаковы; и «Равные» сравнивают свои значения.

Автор: Hoàng Long Размещён: 06.12.2010 08:21
Вопросы из категории :
32x32