【问题标题】:C# list of custom class .Contains()C# 自定义类列表 .Contains()
【发布时间】:2023-04-07 01:11:01
【问题描述】:

我有一个自定义类列表,在添加到列表之前我想检查列表是否具有相同的实例(不是一个属性 - 全部)

public class Function
{
    public string Name;
    public string RT;
    public int ParamCount;
    public List<string> ParamDT;
    public Function()
    {
        ParamDT = new List<string>();
    }
}

我尝试覆盖 Equals() 和 GetHashCode() 但它没有用 等于()

public override bool Equals(object obj)
    {
        var item = obj as Function;

        if (item == null)
        {
            return false;
        }

        return this.Name == item.Name && this.RT == item.RT &&
            this.ParamCount == item.ParamCount && this.ParamDT.Equals(item.ParamDT);
    }

GetHashCode()

public override int GetHashCode()
    {
        return this.Name.GetHashCode();
    }

【问题讨论】:

  • 能否提供Equals/hashcode方法。如果您只想要每种类型的一个实例,那么集合不是更好的数据结构吗
  • GetHashCode 必须从Equals 中检查的所有属性或字段构建哈希码以与Equals 保持一致。如果您将对象添加到 HashSet&lt;Function&gt; 或将它们用作 Dictionary&lt;K, V&gt; 中的键,这一点很重要。

标签: c#


【解决方案1】:

ParamDT 也是一个列表,您还必须单独检查其项目才能正确比较。

this.ParamDT.Equals(item.ParamDT);

话虽如此,如果您想要对象的单个实例,列表不是您应该使用的结构。尝试在列表中搜索相等性有很多开销,因为您将搜索整个列表。尝试使用基于集合/字典的结构。

您对GetHasCode 函数的实现也不正确。它仅基于Name 属性,而在平等的情况下,您正在使用所有属性,这将导致不良特性。请阅读MSDN documentation 以获得更好的实施。

【讨论】:

    【解决方案2】:

    一个简单的EqualsGetHashCode如下:

        protected bool Equals(Function other)
        {
            return string.Equals(Name, other.Name) && string.Equals(RT, other.RT) && ParamCount == other.ParamCount && Equals(ParamDT, other.ParamDT);
        }
    
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return Equals((Function) obj);
        }
    
        public override int GetHashCode()
        {
            unchecked
            {
                var hashCode = (Name != null ? Name.GetHashCode() : 0);
                hashCode = (hashCode * 397) ^ (RT != null ? RT.GetHashCode() : 0);
                hashCode = (hashCode * 397) ^ ParamCount;
                hashCode = (hashCode * 397) ^ (ParamDT != null ? ParamDT.GetHashCode() : 0);
                return hashCode;
            }
        }
    

    然后您可以使用 HashSet,它是一个不包含重复元素的集合。这将确保没有为检查 List 中的唯一性而编写的代码。链接在这里:https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1?redirectedfrom=MSDN&view=netframework-4.7.2

    【讨论】:

      猜你喜欢
      • 2011-02-07
      • 1970-01-01
      • 2011-01-09
      • 2017-01-28
      • 2012-11-26
      • 1970-01-01
      • 2012-05-08
      • 2020-06-03
      • 2013-06-01
      相关资源
      最近更新 更多