Есть ли способ автоматически генерировать метод 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 и добавьте некоторые тесты для равенства.
Надеюсь, это кому-то поможет!