C# 自定义类型上的不同
我试图在以下自定义类上使用Distinct:C# 自定义类型上的不同,c#,linq,C#,Linq,我试图在以下自定义类上使用Distinct: public class RightOperandValue : IEquatable<RightOperandValue> { public string Value { get; set; } public string DisplayName { get; set; } public int GetHashCode(RightOperandValue obj) { int hashV
public class RightOperandValue : IEquatable<RightOperandValue>
{
public string Value { get; set; }
public string DisplayName { get; set; }
public int GetHashCode(RightOperandValue obj)
{
int hashValue = Value == null ? 0 : Value.GetHashCode();
int hashDisplayName = DisplayName == null ? 0 : DisplayName.GetHashCode();
return hashValue ^ hashDisplayName;
}
public bool Equals(RightOperandValue other)
{
if (Value.Equals(other.Value)
&& DisplayName.Equals(other.DisplayName))
{
return true;
}
return false;
}
}
它给出了两个RightOperationValue实例,其中DisplayName和value的值为“city”
我知道这似乎是一种迂回的方法,但我最终需要Distinct来处理这个自定义类值。我读到实现GetHashCode和Equals是实现它的方法,但它似乎不起作用问题是
Distinct
不使用Equals
使用Equals
和GetHashCode
。但它不会使用您的自定义实现(我不确定您是否试图覆盖那里的GetHashCode
)。您需要使用此方法签名覆盖GetHashCode
:
public override int GetHashCode()
{
// Your hashing algorithm here.
}
尽管如此,您当前的哈希算法并不好。如果
Value
和DisplayName
相同,它们将产生相同的散列。当您将相同的散列异或在一起时,您将得到0。问题是Distinct
不使用Equals
使用Equals
和获取hashcode
。但它不会使用您的自定义实现(我不确定您是否试图覆盖那里的GetHashCode
)。您需要使用此方法签名覆盖GetHashCode
:
public override int GetHashCode()
{
// Your hashing algorithm here.
}
尽管如此,您当前的哈希算法并不好。如果
Value
和DisplayName
相同,它们将产生相同的散列。当您将相同的散列异或在一起时,您将得到0。问题是我没有正确实现IEquatable
public class RightOperandValue : IEquatable<RightOperandValue>
{
public string Value { get; set; }
public string DisplayName { get; set; }
public bool Equals(RightOperandValue other)
{
if (Value == other.Value
&& DisplayName == other.DisplayName)
{
return true;
}
return false;
}
public override int GetHashCode()
{
int hashValue = Value == null ? 0 : Value.GetHashCode();
int hashDisplayName = DisplayName == null ? 0 : DisplayName.GetHashCode();
return hashValue ^ hashDisplayName;
}
}
公共类右操作数值:IEquatable
{
公共字符串值{get;set;}
公共字符串DisplayName{get;set;}
公共布尔等于(右操作数值其他)
{
if(Value==other.Value
&&DisplayName==其他.DisplayName)
{
返回true;
}
返回false;
}
公共覆盖int GetHashCode()
{
int hashValue=Value==null?0:Value.GetHashCode();
int-hashDisplayName=DisplayName==null?0:DisplayName.GetHashCode();
返回hashValue^hashDisplayName;
}
}
问题是我没有正确地实现IEquatable
public class RightOperandValue : IEquatable<RightOperandValue>
{
public string Value { get; set; }
public string DisplayName { get; set; }
public bool Equals(RightOperandValue other)
{
if (Value == other.Value
&& DisplayName == other.DisplayName)
{
return true;
}
return false;
}
public override int GetHashCode()
{
int hashValue = Value == null ? 0 : Value.GetHashCode();
int hashDisplayName = DisplayName == null ? 0 : DisplayName.GetHashCode();
return hashValue ^ hashDisplayName;
}
}
公共类右操作数值:IEquatable
{
公共字符串值{get;set;}
公共字符串DisplayName{get;set;}
公共布尔等于(右操作数值其他)
{
if(Value==other.Value
&&DisplayName==其他.DisplayName)
{
返回true;
}
返回false;
}
公共覆盖int GetHashCode()
{
int hashValue=Value==null?0:Value.GetHashCode();
int-hashDisplayName=DisplayName==null?0:DisplayName.GetHashCode();
返回hashValue^hashDisplayName;
}
}
我已经读了两遍了,我仍然不知道你在问什么。也许只有我一个人,但你可能想把你的问题澄清一下。我也被这个问题弄糊涂了。我的大脑告诉你去看看像.Trim(),.ToUpper()或.String.Compare()这样的函数好的,我会尽力清理它。是的,这有点不规范,对不起。@maccettura希望编辑能让它更具可读性。我已经读了两遍,我仍然不知道你在问什么。也许只有我一个人,但你可能想把你的问题澄清一下。我也被这个问题弄糊涂了。我的大脑告诉你去看看像.Trim(),.ToUpper()或.String.Compare()这样的函数好的,我会尽力清理它。是的,抱歉,这有点难以控制。@maccettura希望编辑能让它更具可读性。“问题是Distinct不使用Equals,它使用GetHashCode”-不,它同时使用这两种。虽然XOR哈希不是很好,但它仍然可以工作。(正是因为使用了Equals和GetHashCode,所以它才起作用。)@Jason Boyd,请参阅。引用它“两个相等的对象返回相等的散列码。然而,相反的情况并非如此:相等的散列码并不意味着对象相等,因为不同(不相等)的对象可以有相同的散列码”<代码>返回0是GetHashCode
的有效实现;当然,这不应该以这种方式实现:一个好的哈希函数是快速的,它可以为不同的输入提供(可能)不同的结果,并且(必须)为相同的输入提供相同的结果。不好的散列的结果是,它比使用更好的散列慢,而且速度会慢,因为更多的对象(平均)将需要使用Equals
方法。糟糕的哈希并不能阻止它产生正确的结果。@Jason,还要注意哈希代码上的冲突是不可避免的:GetHashCode返回一个整数,即2^32个不同的值:当你将GetHashCode应用到几乎无限多个不同的字符串时,你将得到冲突“问题是Distinct不使用Equals,它使用GetHashCode”-不,它同时使用这两个。虽然XOR散列不是很好,但它仍然可以工作。(它可以工作,正是因为Equals和GetHashCode一起使用。)@Jason Boyd,请参见。引用它“两个相等的对象返回相等的散列码。”。然而,事实并非如此:相等的哈希代码并不意味着对象相等,因为不同(不相等)的对象可以有相同的哈希代码。“返回0;
是GetHashCode
的有效实现;当然,不应该这样实现:好的哈希函数很快就会给出(可能)不同输入的结果不同,相同输入的结果相同(强制)OP的哈希算法不是很好,这是事实。不好的哈希算法的后果是,它比使用更好的哈希算法慢,并且会因为对象更多(平均)而变慢将需要使用Equals
方法。糟糕的散列不会阻止它生成正确的结果@