具有一个字段(即整数)的结构-您是否还需要覆盖GetHashCode,Equals等?

时间:2018-10-04 07:41:01

标签: c# performance struct hashset gethashcode

通常当有人谈论结构时,建议您覆盖EqualsGetHashCode等。

如果您的struct仅带有单个整数(或任何其他简单值类型),是否也有必要?

说:

public struct LolCatId
{
    public int Id { get; }

    public LolCatId(int id)
    {
        Id = id;
    }
}

HashSets等中使用时-有什么需要考虑的东西吗?或者在所有情况下,这在您期望的性能方面都能达到理想的效果吗?

1 个答案:

答案 0 :(得分:1)

您最好 override EqualsGetHashCode,因为值类型的默认均衡成员通常基于基于反射(这就是为什么)。

一些默认的Equals实现很奇怪,例如:

  // Wrong Equals optimization demo: 
  // .Net (4.7) doesn't use reflection here but compare bytes 
  // and this decision is incorrect in the context
  struct MyDemo {
    public double x;
  }

...

  byte[] bits = BitConverter.GetBytes(double.NaN);

  bits[1] = 42;

  // a holds "standard" NaN
  MyDemo a = new MyDemo() { x = double.NaN };
  // b holds "modified" NaN
  MyDemo b = new MyDemo() { x = BitConverter.ToDouble(bits, 0)};

  Console.Write(string.Join(Environment.NewLine, 
    $"Are structs equal? {(a.Equals(b) ? "Yes" : "No")}",
    $"Are fields equal?  {(a.x.Equals(b.x) ? "Yes" : "No")}"));

结果:

Are structs equal? No
Are fields equal?  Yes

有关详细信息,请参见

https://blogs.msdn.microsoft.com/seteplia/2018/07/17/performance-implications-of-default-struct-equality-in-c/

让我们站在安全方面,尤其是当两种方法都可以容易实现时,例如您的情况:

public struct LolCatId {
  public int Id { get; }

  public LolCatId(int id) {
    Id = id;
  }

  public override int GetHashCode() => Id;

  public override bool Equals(object obj) => 
    obj is LolCatId other ? other.Id == Id : false;
}