2013-02-01 168 views
-1

假設我有一個ListAobjectA如何比較LINQ中不同大小的兩個列表

objectA有姓名,年齡,rollno,排名

ListBobjectB

objectB有姓名,年齡

我如何可以比較兩個列表,姓名和年齡的基礎上,篩選出罕見的記錄。

+1

看看['IComparer'](http://support.microsoft.com/kb/320727) –

+0

請研究你想要什麼樣的比較。比較可以用太多方式完成。即這些記錄何時被認爲是平等的?你希望那些在兩個列表中都有相同名稱和年齡的記錄作爲你的結果,對嗎? –

回答

1

這裏是類樣品:

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); 

您可根據您的要求修改這個例子。

0

下面是比較不具有共同基類型的不同類型的一個小技巧。創建一個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>對於不同類型可正常工作。但是,我們通常無法比較NameAge屬性,因爲這些屬性未在object中定義。這裏的技巧是,編譯器允許您在IEqualityComparer<object>方法簽名中放置dynamic以代替object,並且這些方法仍然符合合同。因此,我們可以利用動態運行時間來比較objectAobjectB類型的共同屬性。

+0

如果你依賴的是一個屬性,那麼使用動態確實沒有什麼優勢 - 只需定義一個接口並使用強類型比較器 – BrokenGlass

+0

@BrokenGlass以前的答案要求這兩種類型具有相同的基類。這個答案使用動態,以便您可以比較兩種類型_而不需要具有公共基類。動態的優勢在於,您可以假定這些屬性不依賴於繼承或接口(即「鴨式打字」)而存在。 –

+1

我意識到這一點 - 我只是從來沒有這樣做的生產代碼 - 這兩個類實現一個共同的接口是一個很好的解決方案,我認爲 – BrokenGlass