我有什麼似乎是一個常見的問題/模式。同一個對象的兩個集合。該對象有許多屬性和一些嵌套的對象。汽車有一個名爲id的屬性,它是唯一的標識符。比較兩個集合
我想找到LINQ的方式做一個diff,其中包括:在一個收集
- 項目,而不是其他(反之亦然)
- 對於匹配的項目,是否有任何變化(變化將是所有屬性的比較?(我只在乎可設置的屬性,我會用反射這個?)
我有什麼似乎是一個常見的問題/模式。同一個對象的兩個集合。該對象有許多屬性和一些嵌套的對象。汽車有一個名爲id的屬性,它是唯一的標識符。比較兩個集合
我想找到LINQ的方式做一個diff,其中包括:在一個收集
可以使用Enumerable.Except()
方法,這將使用比較器(無論是默認還是一個你提供)來評估哪些對象在bot中^ h序列或只有一個:
var sequenceA = new[] { "a", "e", "i", "o", "u" };
var sequenceB = new[] { "a", "b", "c" };
var sequenceDiff = sequenceA.Except(sequenceB);
如果要執行這兩個序列(A-B) union (B-A)
的完全脫節,你將不得不使用:
var sequenceDiff =
sequenceA.Except(sequenceB).Union(sequenceB.Except(sequenceA));
如果你有一個複雜的類型,你可以寫一個IComparer<T>
爲您的類型T並使用接受比較器的超載。
對於問題的第二部分,您需要滾動您自己的實現來報告哪些類型的屬性不同。有沒有什麼內置到.NET BCL直接。你必須決定這種報告將採取什麼形式?你如何識別和表達複雜類型的差異?你當然可以使用反射這個...但是如果你只處理單一類型,我會避免這種情況,併爲它寫一個專門的差分實用程序。如果你要支持一系列的類型,那麼反思可能會更有意義。
你已經收到了你的上半年的優秀答案。正如LBushkin解釋的那樣,後半部分不能由BCL類直接完成。以下是一個簡單的方法,可以通過所有公共可設置的屬性(注意:在這些情況下,gettor可能不公開!)並逐一比較它們。如果兩個對象100%相等,它將返回true。否則,它會打破早期並返回false:
static bool AllSettablePropertiesEqual<T>(T obj1, T obj2)
{
PropertyInfo[] info1 = obj1.GetType().GetProperties(
BindingFlags.Public |
BindingFlags.SetProperty |
BindingFlags.Instance); // get public properties
PropertyInfo[] info2 = obj2.GetType().GetProperties(
BindingFlags.Public |
BindingFlags.SetProperty |
BindingFlags.Instance); // get public properties
// a loop is easier than linq here, and we can break out quick:
for (var i = 0; i < info1.Length; i++)
{
var value1 = info1[i].GetValue(obj1, null);
var value2 = info2[i].GetValue(obj2, null)
if(value1 == null || value2 ==null)
{
if(value1 != value2)
return false;
}
else if (!value1.Equals(value2))
{
return false;
}
}
return true;
}
你可以將這個方法很容易地添加到標準LINQ表達式,像這樣:
var reallyReallyEqual = from itemA in listA
join itemB in listB
on AllSettablePropertiesEqual(itemA, itemB)
select itemA;
的問題是,我想相反。我想要一個基於IEqualityComparer但是具有不同屬性的「相同」項目的列表。我基本上想要所有字段差異的項目列表 – leora 2010-08-05 13:45:39
@ooo:要找到差異,請使用相同的方法,但通過在'AllSettableProperties'前面放置一個'!'來更改連接語句。它返回一個不同的項目列表。爲了找到差異本身,您也可以使用上面的反射示例,只需更改方法以返回具有差異的對的列表。 – Abel 2010-08-05 17:03:14