【问题标题】:HashSet<T> quickly checking if identity exists by T.identityHashSet<T> 通过 T.identity 快速检查身份是否存在
【发布时间】:2013-11-22 11:32:09
【问题描述】:

我有一个名为 Feature 的实体,其中包含一个名为 FeatureIdentity 的值标识。

我有这些实体的列表,我想快速确定身份是否已经存在。

关键是我需要能够通过 FeatureIdentity 进行比较,而不是 Feature,列表中的 Contains 过程正在检查提供的 T 参数。

所以我目前正在做代码:

public class SomeClass
{
    HashSet<Feature> features = new HashSet<Feature>();

    public void SetRequirement(FeatureIdentity feature, FeatureIdentity requires)
    {
        if (ContainsFeature(feature) == false || ContainsFeature(requires) == false)
        {
            // throw
        }
        this.requirements.Add(feature, requires);
    }

    bool ContainsFeature(FeatureIdentity identity)
    {
        return this.features.Where(x => x.Id.Equals(identity)).Count() > 0;
    }
}

Linq 是否对此进行了优化,或者这是检查项目是否存在的正确最佳方法?

public class Feature
{
   public Feature(FeatureIdentity id, string name)
   {
      this.id = id;
      this.name = name;
   }

   FeatureIdentity id;
   string name;

   FeatureIdentity Id
   {
      get { return this.id; }
   }
}

public class FeatureIdentity : IEquatable<FeatureIdentity>
{
    private readonly string sku;

    public FeatureIdentity(string sku)
    {
        this.sku = sku;
    }

    public bool Equals(FeatureIdentity other)
    {
        return this.sku == other.sku;
    }

    public string Sku
    {
        get { return this.sku; }
    }

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

【问题讨论】:

  • 为什么是HashSet&lt;Feature&gt; 而不是HashSet&lt;FeatureIdentity&gt;
  • 因为我想要一个功能列表(其中包含其他属性,例如名称,以及我为使示例更简洁而省略的其他属性)。我们只需要能够快速确定一个对象是否已经在该列表中,基于它的身份
  • 好的,那么为什么是一组特征而不是特征列表呢?您没有向我们展示您对该系列的其他用途,这很重要。仅供参考,ContainsFeature 的现有实现已经导致集合退化为列表,因此它对我们可以看到的代码根本没有任何好处。
  • 听起来您需要HashSet&lt;FeatureIdentity&gt;,可能还需要List&lt;Feature&gt;,或者Dictionary&lt;FeatureIdentity, Feature&gt;
  • 感谢@Jon,有很多事情要做,太多了,无法列出,它被用作添加的列表。 @Kris 谢谢,您对Dictionary&lt;FeatureIdentity, Feature&gt; 的建议似乎可以解决问题

标签: c# linq containers hashset


【解决方案1】:

使用 ctor public HashSet()HashSet&lt;Feature&gt; 使用 EqualityComparer&lt;Feature&gt;.Default 作为默认比较器。

如果你使用HashSet&lt;Feature&gt;,,你应该实现IEquatable&lt;Feature&gt;并覆盖GetHashCode

public class Feature: IEquatable<Feature>
{
    public bool Equals(Feature other)
    {
        return this.id.Equals(other.id);
    }

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

那么您可以尝试以下解决方法,从堆中浪费临时对象。

bool ContainsFeature(FeatureIdentity identity)
{
    return this.features.Contain(new Feature(identity, null));
}

【讨论】:

    猜你喜欢
    • 2018-12-21
    • 2015-04-25
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 2017-09-11
    • 2017-04-30
    相关资源
    最近更新 更多