假設我有一個ListA
和objectA
。如何比較LINQ中不同大小的兩個列表
objectA
有姓名,年齡,rollno,排名
等ListB
與objectB
。
objectB
有姓名,年齡
我如何可以比較兩個列表,姓名和年齡的基礎上,篩選出罕見的記錄。
假設我有一個ListA
和objectA
。如何比較LINQ中不同大小的兩個列表
objectA
有姓名,年齡,rollno,排名
等ListB
與objectB
。
objectB
有姓名,年齡
我如何可以比較兩個列表,姓名和年齡的基礎上,篩選出罕見的記錄。
這裏是類樣品:
public interface IHaveNameAndAge
{
string Name { get; set; }
int Age { get; set; }
}
public class ObjectA : IHaveNameAndAge
{
public string Name { get; set; }
public int Age { get; set; }
int RollNo { get; set; }
int Rank { get; set; }
}
public class ObjectB : IHaveNameAndAge
{
public string Name { get; set; }
public int Age { get; set; }
}
public class MyEqualityComparer : IEqualityComparer<IHaveNameAndAge>
{
public bool Equals(IHaveNameAndAge x, IHaveNameAndAge y)
{
if (ReferenceEquals(x, y))
return true;
return x.Age == y.Age && String.Equals(x.Name, y.Name, StringComparison.Ordinal);
}
public int GetHashCode(IHaveNameAndAge obj)
{
return obj.Age.GetHashCode()^obj.Name.GetHashCode();
}
}
下面是測試代碼:
var listA = new List<ObjectA>();
listA.Add(new ObjectA() { Name = "A", Age = 20 });
listA.Add(new ObjectA() { Name = "B", Age = 25 });
var listB = new List<ObjectB>();
listB.Add(new ObjectB() { Name = "A", Age = 20 });
listB.Add(new ObjectB() { Name = "C", Age = 29 });
var myComparer = new MyEqualityComparer();
var result = listA.Intersect<IHaveNameAndAge>(listB, myComparer);
您可根據您的要求修改這個例子。
下面是比較不具有共同基類型的不同類型的一個小技巧。創建一個IEqualityComparer<object>
如:
public class DynamicComparer : IEqualityComparer<object>
{
public bool Equals(dynamic x, dynamic y)
{
return x.Name == y.Name && x.Age == y.Age;
}
public int GetHashCode(dynamic obj)
{
return ((string)obj.Name).GetHashCode() * 31
+ ((int)obj.Age).GetHashCode();
}
}
然後,你可以這樣做:
var filtered = ListA.Intersect(ListB, new DynamicComparer())
.Cast<objectA>().ToList();
它是如何工作。由於object
是所有類型的通用基本類型,因此IEqualityComparer<object>
對於不同類型可正常工作。但是,我們通常無法比較Name
和Age
屬性,因爲這些屬性未在object
中定義。這裏的技巧是,編譯器允許您在IEqualityComparer<object>
方法簽名中放置dynamic
以代替object
,並且這些方法仍然符合合同。因此,我們可以利用動態運行時間來比較objectA
和objectB
類型的共同屬性。
如果你依賴的是一個屬性,那麼使用動態確實沒有什麼優勢 - 只需定義一個接口並使用強類型比較器 – BrokenGlass
@BrokenGlass以前的答案要求這兩種類型具有相同的基類。這個答案使用動態,以便您可以比較兩種類型_而不需要具有公共基類。動態的優勢在於,您可以假定這些屬性不依賴於繼承或接口(即「鴨式打字」)而存在。 –
我意識到這一點 - 我只是從來沒有這樣做的生產代碼 - 這兩個類實現一個共同的接口是一個很好的解決方案,我認爲 – BrokenGlass
看看['IComparer'](http://support.microsoft.com/kb/320727) –
請研究你想要什麼樣的比較。比較可以用太多方式完成。即這些記錄何時被認爲是平等的?你希望那些在兩個列表中都有相同名稱和年齡的記錄作爲你的結果,對嗎? –