我需要多次调用来自不同IEnumerables的linq区别。 这些差异通常需要我仅在软件中使用一次的条件。 我发现创建用于通过代码库实现IEqualityComparer的类以执行区别的约束确实令人烦恼,因此我想弥补创建空白类的空白,该类允许指向作为区别的参数传递的lambda表达式。 / p>
为了传递自定义IEqualityComparer参数,我开发了以下类:
public class InlineComparer<T>
{
private class LambdaBasedComparer : IEqualityComparer<T>
{
public LambdaBasedComparer(Func<T, int> getHashCode)
{
fGetHashCode = getHashCode;
}
public bool Equals(T x, T y)
{
return x?.GetHashCode() == y?.GetHashCode();
}
private Func<T, int> fGetHashCode { get; set; }
public int GetHashCode(T obj)
{
return fGetHashCode(obj);
}
}
public static IEqualityComparer<T> GetComparer(Func<T, int> getHashCode)
{
return new LambdaBasedComparer(getHashCode);
}
}
您如何看待?希望对您有所帮助!
当然,此帮助程序的完整实现将此类使用到类似于“ IEnumerable.Distinct(Func getHashCode)”的扩展方法中,但是我想强调一下使用lambda传递独特代码的可能性。
答案 0 :(得分:0)
如果相等对象为GetHashCode()返回相同的值,则它们将声明两个对象相等。当然,在定义自己的平等比较器时,您可以随意定义平等的概念,只要平等是自反的,对称的和可传递的(x == x;如果x == y,则y == x ;如果x == y和y == x,则x == z)。
您的平等比较器符合这些规则,因此您可以使用它。
但是!它将是一个有用的比较器吗?
您要使用特殊的相等比较器代替默认的相等比较器,因为您需要对两个对象的(非)相等性进行特殊定义。
通常,在设计过程中,应首先定义对象的相等性。如果这样做了,并且想使用LambdaBasedComparer,则必须创建一个哈希函数,该哈希函数将为不同的对象返回不同的值。
通常,哈希函数有一个要求:两个相等的对象应返回相同的哈希值。不需要两个不同的对象。
只有Int32.MaxValue的Hash值不同,因此,如果您设计的类具有大于此值的可能的不相等实例,则不能使用比较器。一个简单的例子:尝试创建一个使用普通等式的LambdaBasedComparer<long>
。
但是,即使您的类只能创建一半的Int32.MaxValue实例,也很难创建合适的哈希函数来为不同的对象生成唯一的哈希值。
最后,如果使用等式来比较派生类,则等式不会非常直观。考虑Person类和派生类Employee和Customer。
IEqualityComparer<Person> personComparer = new LambdBasedComparer<Person>(...);
Person p = new Person(...);
Person e = new Employee(...);
Person c = new Customer(...);
现在我可以说,某个不是雇员的人可以等于您的一名雇员。但是您会说员工将等于客户吗?
总结:您认为比较器有一个简单的解决方案,但是很难为您的相等性定义创建合适的哈希函数,并且测试该哈希函数可能会更加困难>