In Java when you want to have remove correctly object from a generic Collection
by remove()
method you have to implement equals(Object o)
and remove()
method which can be automatically generated in Eclipse. Example of that method looks like that ---> below.
How to automatically generate that method in C# (Visual Studio, I'm on VS2013)?
Maybe it is not necessary to make List.Remove()
method working properly?
IF it is not possible automatically how the reference Equals
methods should look like? I mean how it should look like.
Is Equals()
method is even used in List.Remove()
if so could you show me how the Equals()
should be implemented to return true if we compare THE SAME OBJECTS (same address in memory)
@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;
}
It is because the framework requires that two objects that are the same must have the same hashcode. If you override the equals method to do a special comparison of two objects and the two objects are considered the same by the method, then the hash code of the two objects must also be the same.
You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object. hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.
For a value type, you should always override Equals, because tests for equality that rely on reflection offer poor performance. You can also override the default implementation of Equals for reference types to test for value equality instead of reference equality and to define the precise meaning of value equality.
The default implementation of GetHashCode() for reference types returns a hash code that is equivalent to the one returned by the GetHashCode(Object) method. You can override GetHashCode() for immutable reference types.
Lo and behold, since November 2017 even Visual Studio itself can generate meaningful implementation of these methods (at least since version 15.5.2).
Just press ctrl+. or right click inside the class and choose "Quick Actions" and then "Generate Equals and GetHashCode"
Docs for the feature: 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;
}
}
Update: Note tough, that you still might not want to trust VS completely and test Equals, since if your class contains Collection, Equals will depend on reference equality once more as this term is used:
EqualityComparer<IList<Foo>>.Default.Equals(SomeFoos, other.SomeFoos);
OMG anyone? And ReSharper does that too.
Equals()
generation at design timeIf you want to generate it once and then maintain the generated source code manually (e.g. if the class changes), Resharper is a useful tool, as @ThomasWeller already mentioned in his answer.
Note that this approach has potential for hard to find bugs, because you need to remember to adapt the Equals()
implementation when you change the class. To avoid this, use the following approach:
Equals()
generation at runtime (static initialization time)If you want a solution that dynamically generates Equals()
and GetHashCode()
methods at runtime, you can use Equ (I'm the author of that library). Equ generates the equality methods at static initialization time and caches them, so after static initialization, performance is the same as an explicit implementation.
Here is a simple example:
class Address : MemberwiseEquatable<Address>
{
public Address(string street, string city)
{
Street = street;
City = city;
}
public string Street { get; }
public string City { get; }
}
With this, the following expression is true
:
new Address("Baker Street", "London") == new Address("Baker Street", "London")
This is the easiest way of using Equ: Just inherit from MemberwiseEquatable<TSelf>
. Note that there are other possibilities if you can not / don't want to inherit from a base class.
In your last question you want to know how to write an Equals
method that compares objects by "address in memory". This is called reference equality comparison and is the default Equals()
implementation that every class inherits from object
. So to get reference equality on your class, just don't override Equals()
.
You should however think carefully about which objects you want to compare by reference, and which you want to compare by value. If you use the domain-driven design terminology, value objects should be compared by value, whereas entities should be compared by reference or by ID.
No. ReSharper can do that (along with other goodies such as implementing IEquatable<T>
) but plain VS cannot.
I know it's not a full auto-generation, but in Visual Studio 2015, there is a way to auto generate at least the method stub of the Hashcode() and a Equals() function.
In the class you wish to add them to, type Equals
Bring your curser to the end of Equals and hit tab.
Remove the NotImplementedExceptions and add some tests for equality.
I hope this is helpful to someone!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With