Есть ли способ автоматически генерировать метод equals и hashcode в Visual Studio

В Java, когда вы хотите правильно удалить объект из общего метода Collection by remove(), вам нужно реализовать метод equals(Object o) и remove(), который может быть автоматически сгенерирован в Eclipse. Пример этого метода выглядит следующим образом: > ниже.

  • Как автоматически сгенерировать этот метод в С# (Visual Studio, я на VS2013)?

  • Возможно, нет необходимости работать с методом List.Remove()?

  • ЕСЛИ это невозможно, как должны выглядеть ссылочные методы Equals? Я имею в виду, как это должно выглядеть.

  • Метод Equals() используется даже в List.Remove(), если бы вы могли показать мне, как Equals() должен быть реализован для возврата true, если мы сравниваем ОДНЫЕ ОБЪЕКТЫ (тот же адрес в памяти)


  @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((centerPanel == null) ? 0 :          centerPanel.hashCode());
        result = prime * result + ((lowerPanel == null) ? 0 : lowerPanel.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if(this == obj)
            return true;
        if(obj == null)
            return false;
        if(getClass() != obj.getClass())
            return false;
        LayoutDemo other = (LayoutDemo) obj;
        if(centerPanel == null) {
            if(other.centerPanel != null)
                return false;
        } else if(!centerPanel.equals(other.centerPanel))
            return false;
        if(lowerPanel == null) {
            if(other.lowerPanel != null)
                return false;
        } else if(!lowerPanel.equals(other.lowerPanel))
            return false;
        return true;
    }

Ответ 1

Автоматическая генерация Equals() во время разработки

Если вы хотите сгенерировать его один раз, а затем сохранить сгенерированный исходный код вручную (например, если класс изменится), Resharper - полезный инструмент, как @ThomasWeller уже упомянул в своем ответе.

Обратите внимание, что этот подход может затруднить поиск ошибок, потому что вам нужно запомнить адаптацию реализации Equals() при изменении класса. Чтобы этого избежать, используйте следующий подход:

Автоматическая генерация Equals() во время выполнения (статическое время инициализации)

Если вам нужно решение, которое динамически генерирует методы Equals() и GetHashCode() во время выполнения, вы можете использовать Equ (I ' м автора этой библиотеки). Equ генерирует методы равенства при статическом времени инициализации и кэширует их, поэтому после статической инициализации производительность такая же, как явная реализация.

Вот простой пример:

class Address : MemberwiseEquatable<Address>
{
  public Address(string street, string city)
  {
    Street = street;
    City = city;
  }

  public string Street { get; }
  public string City { get; }
}

При этом следующее выражение true:

new Address("Baker Street", "London") == new Address("Baker Street", "London")

Это самый простой способ использования Equ: просто наследовать от MemberwiseEquatable<TSelf>. Обратите внимание, что есть другие возможности, если вы не можете/не хотите наследовать от базового класса.

Замечание о сравнении по значению vs по ссылке

В последнем вопросе вы хотите знать, как написать метод Equals, который сравнивает объекты по "адресу в памяти". Это называется сравнением сравнения ссылок и является реализацией по умолчанию Equals(), которую каждый класс наследует от object. Итак, чтобы получить ссылочное равенство в вашем классе, просто не переопределить Equals().

Однако вы должны тщательно подумать о том, какие объекты вы хотите сравнить по ссылке и которые вы хотите сравнить по значению. Если вы используете терминологию, основанную на домене, объекты ценности должны сравниваться по значению, тогда как сущности должны сравниваться по ссылке или по идентификатору.

Ответ 2

И вот, с ноября 2017 года даже сама Visual Studio может генерировать значимую реализацию этих методов (по крайней мере, начиная с версии 15.5.2).

Просто нажмите ctrl + . или щелкните правой кнопкой мыши внутри класса и выберите "Быстрые действия", а затем "Generate Equals и GetHashCode"

Документы для функции: https://docs.microsoft.com/en-us/visualstudio/ide/reference/generate-equals-gethashcode-methods

    public class Foo
    {
       public Bar Bar { get; set; }
       public string FooBar { get; set; }

    public override bool Equals(object obj)
    {
        var foo = obj as Foo;
        return foo != null &&
               EqualityComparer<Bar>.Default.Equals(Bar, foo.Bar) &&
               FooBar == foo.FooBar;
    }

    public override int GetHashCode()
    {
        var hashCode = 181846194;
        hashCode = hashCode * -1521134295 + EqualityComparer<Bar>.Default.GetHashCode(Bar);
        hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(FooBar);
        return hashCode;
    }

}

Обновление: обратите внимание, что вы все еще не можете полностью доверять VS и проверять Equals, поскольку, если ваш класс содержит коллекцию, Equals будет снова зависеть от ссылочного равенства, поскольку этот термин используется:

EqualityComparer<IList<Foo>>.Default.Equals(SomeFoos, other.SomeFoos);

Боже, кто-нибудь? И ReSharper тоже это делает.

Ответ 3

Нет. ReSharper может это сделать (наряду с другими лакомствами, такими как реализация IEquatable<T>), но простой VS не может.

Ответ 4

Я знаю, что это не полное автогенерация, но в Visual Studio 2015 есть способ автоматически генерировать по крайней мере метод заглушки функции Hashcode() и Equals().

  • В классе, к которому вы хотите добавить, введите Equals введите описание изображения здесь

  • Принесите свой курсор в конец Equals и нажмите вкладку. введите описание изображения здесь

  • Удалите NotImplementedExceptions и добавьте некоторые тесты для равенства.

Надеюсь, это кому-то поможет!