c# Linq distinct不會調(diào)用Equals方法詳解
我有以下課程
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();
}
}
我使用如下方法將一些數(shù)據(jù)加載到該類的列表中:
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();
}
問題是Distinct()調(diào)用似乎沒有做到這一點.仍然存在彼此相等的對象.
根據(jù)這篇文章:https://msdn.microsoft.com/en-us/library/vstudio/bb348436%28v=vs.100%29.aspx
這就是你應(yīng)該如何做出不同的工作,但它似乎并沒有在ModInfo對象上調(diào)用Equals方法.
是什么導(dǎo)致這種情況發(fā)生?
示例值:
modinfo[0]: id=2069, MD5 =0AAEBF5D2937BDF78CB65807C0DC047C
modinfo[1]: id=2208, MD5 = 0AAEBF5D2937BDF78CB65807C0DC047C
我不關(guān)心選擇哪個值,因為md5值相同,它們可能是相同的.
您還需要覆蓋Object.Equals,而不僅僅是實現(xiàn)IEquatable.
如果你把它添加到你的班級:
public override bool Equals(object other)
{
ModInfo mod = other as ModInfo;
if (mod != null)
return Equals(mod);
return false;
}
它應(yīng)該工作.
有關(guān)詳細(xì)信息,請參閱此文章:Implementing IEquatable Properly
編輯:好的,這是基于GetHashCode的最佳實踐的略有不同的實現(xiàn).
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;
}
}
}
你可以驗證它:
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();
補(bǔ)充知識:C#中通過Distinct方法對List集合進(jìn)行去重
在C#的List集合對象中,可以使用Distinct方法來對List集合元素進(jìn)行去重,如果list集合內(nèi)部元素為值類型,則Distinct方法根據(jù)值類型是否相等來判斷去重,如果List集合內(nèi)部元素為引用類型變量,則是判斷相同引用的對象為相同進(jìn)行List集合元素去重操作。
(1)值類型的List集合對象intList,內(nèi)部元素為1,1,2,2,3,4,5等這幾個元素。對intList對象進(jìn)行去重可使用下列語句:
List intList= new List() { 1, 1,2,2,3,4,5};
intList= intList.Distinct().ToList();
經(jīng)過上述Distinct方法去重處理并重新賦值后,intList集合內(nèi)部元素為:1,2,3,4,5。
(2)針對引用類型的Distinct方法去重,則是判斷List集合中的對象引用地址是否一致,不一致的話為不同的兩個對象,即使2個對象的每個屬性值都一樣的情況下。
List testList = new List<ConsoleApplication1.TestModel>();
testList.Add(new TestModel()
{
Index=1,
Name=“Index1”
});
testList.Add(new TestModel()
{
Index = 2,
Name = “Index2”
});
testList.Add(new TestModel()
{
Index = 2,
Name = “Index2”
});
testList = testList.Distinct().ToList();
上述程序語句中,雖然List集合testList中的第2個元素和第3個元素的屬性值完全一樣,但這2個元素依舊是不同的對象,因此在調(diào)用Distinct()方法去重后重新賦值,testList依舊不變。
以上這篇c# Linq distinct不會調(diào)用Equals方法詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

