c# - 如何为由字符串和 int32 集合组成的对象编写 GetHashCode 方法?
问题描述
有一类产品:
public class ProductWithFeatures
{
public string Name { get; set; }
public ICollection<Feature> Features { get; set; }
}
public class Feature
{
public int Id { get; set; }
public Feature(int Id)
{
this.Id = Id;
}
}
我想为此编写一个 IEqualityComparer(我已经有一个用于功能的)。
Feature 是这样的:
public class FeatureComparer : IEqualityComparer<Feature>
{
public bool Equals(Feature x, Feature y)
{
return x.Id == y.Id;
}
public int GetHashCode(Feature obj)
{
return obj.Id;
}
}
到目前为止,我在另一个上写的是这样的:
public class ProductComparer : IEqualityComparer<LinqHomework.ProductWithFeatures>
{
public bool Equals(ProductWithFeatures x, ProductWithFeatures y)
{
return x.Name == y.Name && LinqHomework.FeatureComparer.Equals(x.Features, y.Features);
}
public int GetHashCode(ProductWithFeatures obj)
{
}
}
我在任何地方都找不到关于这个的答案。有人知道怎么写吗?
解决方案
如果两个ProductWithFeatures
s 具有相同的名称,并且按相同的顺序具有相同的特征,则它们是相等的。
public class ProductComparer : IEqualityComparer<LinqHomework.ProductWithFeatures>
{
public bool Equals(ProductWithFeatures x, ProductWithFeatures y)
{
return x.Name == y.Name && x.Features.SequenceEqual(y.Features, new LinqHomework.FeatureComparer());
}
public int GetHashCode(ProductWithFeatures obj)
{
int hash = obj.Name.GetHashCode();
var featureComparer = new LinqHomework.FeatureComparer();
foreach (var feature in obj.Features)
{
hash = hash * 23 + featureComparer.GetHashCode(feature);
}
return hash;
}
}
这是一种简单的方法,可以通过多种方式进行改进。
首先,让我们给我们FeatureComparer
一个Default
属性,所以我们不需要继续创建新实例:
public class FeatureComparer : IEqualityComparer<Feature>
{
public static FeatureComparer Default { get; } = new FeatureComparer();
// ... as before
}
这让我们可以写:
public class ProductComparer : IEqualityComparer<LinqHomework.ProductWithFeatures>
{
public bool Equals(ProductWithFeatures x, ProductWithFeatures y)
{
return x.Name == y.Name && x.Features.SequenceEqual(y.Features, LinqHomework.FeatureComparer.Default);
}
public int GetHashCode(ProductWithFeatures obj)
{
int hash = obj.Name.GetHashCode();
foreach (var feature in obj.Features)
{
hash = hash * 23 + LinqHomework.FeatureComparer.Default.GetHashCode(feature);
}
return hash;
}
}
我们也没有处理我们的方法被传递的情况null
,或者特性的名称是null
,所以让我们来处理这些。我们还可以测试x
和是否y
是同一个对象Equals
。
我们还将在一个unchecked
块中执行整数运算,以防它溢出(并且程序集是用 编译的/checked
)。
请注意,我们使用ReferenceEquals
而不是==
,以防您最终==
在类型中实现运算符。
public class ProductComparer : IEqualityComparer<LinqHomework.ProductWithFeatures>
{
public bool Equals(ProductWithFeatures x, ProductWithFeatures y)
{
if (ReferenceEquals(x, y))
return true;
if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
return false;
if (x.Name != y.Name)
return false;
if (ReferenceEquals(x.Features, y.Features))
return true;
if (ReferenceEquals(x.Features, null) || ReferenceEquals(y.Features, null))
return false;
if (!x.Features.SequenceEquals(y.Features, LinqHomework.FeatureComparer.Default))
return false;
return true;
}
public int GetHashCode(ProductWithFeatures obj)
{
if (ReferenceEquals(obj, null))
return 0;
unchecked
{
int hash = obj.Name?.GetHashCode() ?? 0;
if (!ReferenceEquals(obj.Features, null))
{
foreach (var feature in obj.Features)
{
hash = hash * 23 + LinqHomework.FeatureComparer.Default.GetHashCode(feature);
}
return hash;
}
}
}
}
推荐阅读
- amazon-web-services - API Gateway + GovCloud + 带有 SSL 证书的自定义域名
- java - doFilter 和 HandlerInterceptorAdapter 可以在单个 spring 应用程序中一起使用吗
- windows - 检测 PE 文件中的无效资源部分
- matlab - 在matlab中生成特定的数字序列块
- javascript - Type .. 的参数不能分配给 Typescript 和单元测试中的 .. 类型的参数
- php - 将字符串转换为 JSON 并在 php 中另存为 .json 文件
- java - 将新元素插入表时执行任务
- c# - 将组合框项目显示到图表中
- angular - Angular ngx-translate getTranslation 问题
- prolog - PROLOG:推理过程,为什么返回false