代码之家  ›  专栏  ›  技术社区  ›  Dirk Boer

带一个字段(即整数)的结构-是否仍需要重写GetHashCode、Equals等?

  •  1
  • Dirk Boer  · 技术社区  · 6 年前

    通常,当有人谈论结构时,建议您重写 Equals GetHashCode 等等。

    如果你有一个 struct 只需要一个 (或任何其他 简单值类型 )?

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

    HashSets

    1 回复  |  直到 6 年前
        1
  •  1
  •   Dmitrii Bychenko    6 年前

    Equals GetHashCode 基于反射的 缓慢的 ).

    还有一些违约 等于 实现非常简单 ,例如:

      // 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;
    }