为类重写Equals/GetHashCode以便使用hashset Contains/ExceptWith/UnionW
本文关键字:hashset Contains UnionW ExceptWith 重写 Equals GetHashCode | 更新日期: 2023-09-27 18:11:35
我目前有一个c#类,如下所示:
namespace DBModel
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
public partial class ConnSrv
{
public int ID { get; set; }
[Required]
[StringLength(14)]
public string Service { get; set; }
[Required]
[StringLength(14)]
public string ConnectsToService { get; set; }
public virtual Service Service1 { get; set; }
public virtual Service Service2 { get; set; }
}
}
在我的主程序中,我创建了哈希集来处理这些对象。我遇到的问题是,我希望能够在这些哈希集上使用诸如Contains、Except、ExceptWith、UnionWith等操作符。
要使ConnSrv的对象被认为是"相等的",Service和ConnectsToService的值必须相等。因此,我意识到,在某种程度上,我必须重写类的Equals和GetHashCode操作符。我只是不确定如何做到这一点,是通过直接重写对象类,还是通过实现IEquatable或IEquatable,还是通过其他方法。下面是几个简单的例子,说明了我对最终结果的期望。如果我不合适,请告诉我。提前感谢您的时间。
var testHS1 = new HashSet<ConnectingService>();
testHS1.Add(test1);
testHS1.Contains(test2); // Returns true
var testHS2 = new HashSet<ConnectingService>();
testHS2.Add(test1);
testHS2.Add(test2);
testHS2.Add(test3);
testHS2.Except(testHS1); // Expect end result to only contain test3
如何覆盖Equals
public override bool Equals(object obj)
{
if (obj == null)
return false;
ConnSrv c = obj as ConnSrv;
if (c == null)
return false;
if (ID == c.ID)
return true;
return false;
}
public override int GetHashCode()
{
int result = ID.GetHashCode();
return result;
}
我只是不确定如何做到这一点,是否通过对象类的直接覆盖,通过实现IEquatable或IEquatable,或通过其他方法。
覆盖object.Equals
和object.GetHashCode
就足够了。您也可以选择性地实现IEquatable
,但是对于引用类型,唯一的好处是分钟性能改进,因为您不必从object
强制转换。如果你实现IEquatable
,你也必须覆盖object.Equals(object)
和object.GetHashCode()
。
在使用HashSet
时更重要的是遵循GetHashCode
的规则,特别是两个"相等"的对象具有相同的哈希码。
谢谢Alex!这为我指明了正确的道路。我添加了下面的代码,似乎已经开始比赛了。
public override int GetHashCode()
{
return (Service.GetHashCode() * ConnectsToService.GetHashCode()).GetHashCode();
}
public bool Equals(ConnectingService c1)
{
return c1.Service == this.Service && c1.ConnectsToService == this.ConnectsToService;
}