Is there a way to automatically generate equals an

2019-06-16 03:56发布

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.

  1. How to automatically generate that method in C# (Visual Studio, I'm on VS2013)?

  2. Maybe it is not necessary to make List.Remove() method working properly?

  3. IF it is not possible automatically how the reference Equals methods should look like? I mean how it should look like.

  4. 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;
    }

4条回答
叛逆
2楼-- · 2019-06-16 04:12

No. ReSharper can do that (along with other goodies such as implementing IEquatable<T>) but plain VS cannot.

查看更多
Deceive 欺骗
3楼-- · 2019-06-16 04:23

Automatic Equals() generation at design time

If 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:

Automatic 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.

Remark on compare by value vs by reference

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.

查看更多
Root(大扎)
4楼-- · 2019-06-16 04:23

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.

  1. In the class you wish to add them to, type Equals enter image description here

  2. Bring your curser to the end of Equals and hit tab. enter image description here

  3. Remove the NotImplementedExceptions and add some tests for equality.

I hope this is helpful to someone!

查看更多
迷人小祖宗
5楼-- · 2019-06-16 04:27

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 tought, 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.

查看更多
登录 后发表回答