[英]Linq distinct doesn't call Equals method
I have the following class 我有以下课程
public class ModInfo : IEquatable<ModInfo>
{
public int ID { get; set; }
public string MD5 { get; set; }
public bool Equals(ModInfo other)
{
return other.MD5.Equals(MD5);
}
public override int GetHashCode()
{
return MD5.GetHashCode();
}
}
I load some data into a list of that class using a method like this: 我使用如下方法将一些数据加载到该类的列表中:
public void ReloadEverything() {
var beforeSort = new List<ModInfo>();
// Bunch of loading from local sqlite database.
// not included since it's reload boring to look at
var modinfo = beforeSort.OrderBy(m => m.ID).AsEnumerable().Distinct().ToList();
}
Problem is the Distinct()
call doesn't seem to do it's job. 问题是
Distinct()
调用似乎没有做到这一点。 There are still objects which are equals each other. 仍然存在彼此相等的对象。
Acording to this article: https://msdn.microsoft.com/en-us/library/vstudio/bb348436%28v=vs.100%29.aspx that is how you are supposed to make distinct work, however it doesn't seem to be calling to Equals method on the ModInfo object. 根据这篇文章: https ://msdn.microsoft.com/en-us/library/vstudio/bb348436%28v=vs.100%29.aspx这是你应该如何做出截然不同的工作,但它没有似乎是在ModInfo对象上调用Equals方法。 What could be causing this to happen?
是什么导致这种情况发生?
Example values: 示例值:
modinfo[0]: id=2069, MD5 =0AAEBF5D2937BDF78CB65807C0DC047C
modinfo[1]: id=2208, MD5 = 0AAEBF5D2937BDF78CB65807C0DC047C
I don't care which value gets chosen, they are likely to be the same anyway since the md5 value is the same. 我不关心选择哪个值,因为md5值相同,它们可能是相同的。
You also need to override Object.Equals
, not just implement IEquatable
. 您还需要覆盖
Object.Equals
,而不仅仅是实现IEquatable
。
If you add this to your class: 如果你把它添加到你的班级:
public override bool Equals(object other)
{
ModInfo mod = other as ModInfo;
if (mod != null)
return Equals(mod);
return false;
}
It should work. 它应该工作。
See this article for more info: Implementing IEquatable Properly 有关更多信息,请参阅此文章: 正确实现IEquatable
EDIT: Okay, here's a slightly different implementation based on best practices with GetHashCode. 编辑:好的,这是基于GetHashCode的最佳实践的略有不同的实现。
public class ModInfo : IEquatable<ModInfo>
{
public int ID { get; set; }
public string MD5 { get; set; }
public bool Equals(ModInfo other)
{
if (other == null) return false;
return (this.MD5.Equals(other.MD5));
}
public override int GetHashCode()
{
unchecked
{
int hash = 13;
hash = (hash * 7) + MD5.GetHashCode();
return hash;
}
}
public override bool Equals(object obj)
{
ModInfo other = obj as ModInfo;
if (other != null)
{
return Equals(other);
}
else
{
return false;
}
}
}
You can verify it: 你可以验证它:
ModInfo mod1 = new ModInfo {ID = 1, MD5 = "0AAEBF5D2937BDF78CB65807C0DC047C"};
ModInfo mod2 = new ModInfo {ID = 2, MD5 = "0AAEBF5D2937BDF78CB65807C0DC047C"};
// You should get true here
bool areEqual = mod1.Equals(mod2);
List<ModInfo> mods = new List<ModInfo> {mod1, mod2};
// You should get 1 result here
mods = mods.Distinct().ToList();
What's with those specific numbers in GetHashCode? GetHashCode中的那些具体数字是什么?
Add 加
public bool Equals(object other)
{
return this.Equals(other as ModInfo)
}
Also see here the recommendations how to implement the equality members: https://msdn.microsoft.com/en-us/library/ms173147(v=vs.80).aspx 另请参阅此处有关如何实现平等成员的建议: https : //msdn.microsoft.com/en-us/library/ms173147(v = vs。80).aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.