【问题标题】:Is there a way to automatically generate equals and hashcode method in Visual Studio有没有办法在 Visual Studio 中自动生成 equals 和 hashcode 方法
【发布时间】:2014-01-08 12:34:41
【问题描述】:

在 Java 中,当您想通过 remove() 方法从通用 Collection 中正确删除对象时,您必须实现可以在 Eclipse 中自动生成的 equals(Object o)remove() 方法。该方法的示例如下所示 --->。

  1. 如何在 C# 中自动生成该方法(Visual Studio,我在 VS2013)?

  2. 也许没有必要让List.Remove() 方法正常工作?

  3. 如果不可能自动引用Equals 方法应该是什么样子?我的意思是它应该是什么样子。

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

【问题讨论】:

  • 自动是什么意思?甚至 eclipse 也不知道你想如何实现这些方法,那么你的自定义对象的相等意味着什么。如果你只想创建方法体,让你的类实现IEqualityComparer。如果单击界面下方的红色错误线,Visual Studio 会建议自动创建它们。但它们将只包含throw new NotImplementedException();
  • @TimSchmelter 它确实知道,上面的例子。
  • 所以 Eclipse 将你的类的所有属性添加到 EqualsGetHashCode 或者只是一个或没有?什么是上面自动生成的,一切? EqualsGethashCode 对于复杂的对象来说并不是微不足道的。
  • @TimSchmelter Is Equals() 方法甚至在 List.Remove() 中使用如果是这样,如果我们比较相同的对象(内存中的相同地址),你能否告诉我如何实现 Equals() 以返回 true )
  • Equals 用于List.Remove 并通过引用比较两个对象:Object.ReferenceEquals(obj1, obj2)。首先阅读文档总是值得的。您将在备注部分找到相关信息。

标签: c# .net visual-studio list


【解决方案1】:

你瞧,自 2017 年 11 月以来,甚至 Visual Studio 本身也可以生成这些方法的有意义的实现(至少从 15.5.2 版开始)。

只需按 ctrl+. 或在类内右键单击并选择“快速操作”,然后选择“Generate Equals and 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,因为如果您的类包含 Collection,则使用该术语时,Equals 将再次依赖于引用相等:

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

天哪,有人吗? ReSharper 也能做到这一点。

【讨论】:

  • 看起来 VS for Mac 社区版也有这个选项,但是当我点击它时没有任何反应。
  • “你试过把它关掉再打开吗?”,必须经常在VS上使用这种技术……除此之外,我只能考虑升级到最新版本。我在 Windows 上尝试了 Enterprise 版和 Communit 版,都运行良好。
  • 是的,我使用的是最新版本。
  • 你需要在声明类的那一行右击。此外,如果您的类已经包含 Equals 方法,您将不会看到该选项。
【解决方案2】:

在设计时自动生成Equals()

如果您想生成一次,然后手动维护生成的源代码(例如,如果类更改),Resharper 是一个有用的工具,正如@ThomasWeller 在他的回答中已经提到的那样。

请注意,这种方法可能很难找到错误,因为您需要记住在更改类时调整 Equals() 实现。为避免这种情况,请使用以下方法:

在运行时自动生成Equals()(静态初始化时间)

如果您想要一个在运行时动态生成Equals()GetHashCode() 方法的解决方案,您可以使用Equ(我是该库的作者)。 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&lt;TSelf&gt; 继承即可。请注意,如果您不能/不想从基类继承,还有其他可能性。

关于比较按值 vs 按引用的备注

在您的最后一个问题中,您想知道如何编写一个Equals 方法,通过“内存中的地址”来比较对象。这称为引用相等比较并且是默认的Equals() 实现,每个类都从object 继承。因此,要在您的类上获得引用相等性,只需不要覆盖 Equals()

但是,您应该仔细考虑要通过引用比较哪些对象,以及要按值比较哪些对象。如果您使用领域驱动设计术语,值对象应该按值比较,而实体应该按引用或ID比较。

【讨论】:

    【解决方案3】:

    没有。 ReSharper 可以做到这一点(以及其他好处,例如实现 IEquatable&lt;T&gt;),但普通 VS 不能。

    【讨论】:

      【解决方案4】:

      我知道这不是完全自动生成,但在 Visual Studio 2015 中,有一种方法可以自动生成至少 Hashcode() 和 Equals() 函数的方法存根。

      1. 在要添加它们的类中,键入 Equals

      2. 将光标移到 Equals 的末尾并点击 Tab。

      3. 删除 NotImplementedExceptions 并添加一些相等性测试。

      我希望这对某人有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-28
        • 2016-03-17
        • 1970-01-01
        • 2011-09-25
        • 2011-11-05
        相关资源
        最近更新 更多