C# 使用带容差的IEqualityComparer GetHashCode
我正在尝试实现一个对日期比较有容差的C# 使用带容差的IEqualityComparer GetHashCode,c#,linq,hashtable,date-range,iequalitycomparer,C#,Linq,Hashtable,Date Range,Iequalitycomparer,我正在尝试实现一个对日期比较有容差的IEqualityComparer。我也调查过。问题是我无法使用变通方法,因为我正在LINQ中使用IEqualityComparer。GroupJoin()。我尝试了一些允许容忍的实现。我可以让Equals()工作,因为我有两个对象,但我不知道如何实现GetHashCode() 我的最佳尝试如下所示: public class ThingWithDateComparer : IEqualityComparer<IThingWithDate> {
IEqualityComparer
。我也调查过。问题是我无法使用变通方法,因为我正在LINQ中使用IEqualityComparer
。GroupJoin()
。我尝试了一些允许容忍的实现。我可以让Equals()
工作,因为我有两个对象,但我不知道如何实现GetHashCode()
我的最佳尝试如下所示:
public class ThingWithDateComparer : IEqualityComparer<IThingWithDate>
{
private readonly int _daysToAdd;
public ThingWithDateComparer(int daysToAdd)
{
_daysToAdd = daysToAdd;
}
public int GetHashCode(IThingWithDate obj)
{
unchecked
{
var hash = 17;
hash = hash * 23 + obj.BirthDate.AddDays(_daysToAdd).GetHashCode();
return hash;
}
}
public bool Equals(IThingWithDate x, IThingWithDate y)
{
throw new NotImplementedException();
}
}
public interface IThingWithDate
{
DateTime BirthDate { get; set; }
}
公共类ThingWithDateComparer:IEqualityComparer
{
私有只读int_daysToAdd;
公共ThingWithDateComparer(int days添加)
{
_daysToAdd=daysToAdd;
}
公共int GetHashCode(IThingWithDate obj)
{
未经检查
{
var-hash=17;
hash=hash*23+obj.BirthDate.AddDays(_daysToAdd).GetHashCode();
返回散列;
}
}
公共布尔等于(i与日期x,i与日期y)
{
抛出新的NotImplementedException();
}
}
公共接口IThingWithDate
{
日期时间出生日期{get;set;}
}
使用
.GroupJoin()
从GetHashCode()
中构建一个HashTable
,它将天数应用于两个/所有对象。这不起作用。我找不到任何方法为给定的条件生成逻辑哈希代码。散列码用于确定两个日期是否应该粘在一起。如果它们应该组合在一起,那么它们必须返回相同的哈希代码 如果您的“浮动”为5天,这意味着1/1/2000必须生成与1/4/2000相同的哈希代码,而1/4/2000必须生成与1/8/2000相同的哈希代码(因为它们彼此在5天之内)。这意味着2000年1月1日的代码与2000年1月8日的代码相同(因为如果a=b和b=c,a=c)
2000年1月1日和2000年8月1日不在5天“浮动”范围内。从概念上讲,这个问题是不可能的。您试图以一种不具有相等形式的方式比较对象,而相等形式是您试图使用它执行的操作所必需的。例如,
GroupJoin
依赖于这样一个假设:如果A等于B,B等于C,那么A等于C,但在您的情况下,这不是真的。A和B可能“足够接近”,以至于您想要将它们分组,但A和C可能不是
您根本不需要实施
IEqualityComparer
,因为您无法履行它所要求的合同。如果您想创建一个集合中的项目到另一个集合中与之“足够接近”的所有项目的映射,那么您需要自己编写该算法(这样做可能很困难,但这样做不太困难),而不是使用GroupJoin
,因为它无法执行该操作。是否将日期添加公差,如1月5日等于1月6日,公差为1天?这个相等的定义是不可传递的,所以我怀疑除了为每个对象返回相同的哈希代码这一琐碎的解决方案之外,使用IEqualityComparer是否有可能正确实现。算了吧。将GroupJoin
替换为SelectMany
和simpleWhere
(性能不是很好,但应该可以正常工作)。@mikez是的,这就是容差。命名很糟糕。如果我不能做到这一点,我只需要实现一个自定义版本的GroupJoin()
@IvanStoev。性能是个问题。当前的匹配解决方案使用where,它提供了糟糕的性能。通过使用GroupJoin()
我可以将9小时的进程缩短到毫秒。我知道(而且总是关心.poerformance)。但是工作慢总比不工作好。真正的用例是什么,也许我们可以考虑其他的东西?非常正确。我想我将不得不放弃使用GroupJoin
,并实现一个版本,该版本允许一个比较器
,该比较器左侧有一个种子。这似乎是正确的答案。令人失望的是,答案是没有答案。