2010-06-23 35 views
3

我有兩個EmailAddress通用列表,我想要一個簡單的方法來獲取List1中不在List2中的所有EmailAddress對象。LINQ到對象列表區別

我在想Linq的左外連接,但我對如何設置它有點困惑。我也接受更好的解決方案。

更新:我應該注意到這些是我的「EmailAddress」對象的自定義數據類型列表。

回答

2

大多數答案是行不通的,因爲在列表1和列表2項可能會在用戶的面前人人平等,但實際上卻是不同的實例的引用(他們沒有引用相等)。

假設Address是EmailAddress的字符串屬性,這裏是左連接解決方​​案。

IEnumerable<EmailAddress> query = 
    from a1 in list1 
    join a2 in list2 on a1.Address equals a2.Address into g 
    from x in g.DefaultIfEmpty() 
    where x == null 
    select a1; 
+0

如果您正確覆蓋Equals方法以使其有意義,它們將起作用。說實話,這樣的代碼僅僅是一個非常簡單的操作,除非有很好的理由不覆蓋.Equals(我們沒有辦法知道)。 OP現在知道這些東西實際上是如何工作的,這是好事。 – 2010-06-23 20:30:45

+0

你能解釋我將如何重寫這種情況下的Equals方法嗎? – Brandon 2010-06-23 20:46:21

+0

Overriding Equals是將錯誤引入代碼的好方法。指導方針聲明:「建議任何覆蓋Equals的類都會覆蓋System.Object.GetHashCode。」當然,凡人不會正確地重寫GetHashCode。希拉里奇隨之而來。 http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx – 2010-06-23 21:07:34

9

可以使用除LINQ方法:

var list1 = // First list generation 
var list2 = // Second list generation 

var result = list1.Except(list2); 
1

好吧,我相信人們會在這裏給你一個更時尚,LINQesque的例子,但我的僱主只允許我們使用.NET 2.0,所以...

List<EmailAddress> ret = new List<EmailAddress>(); 
foreach (EmailAddress address in List1) 
{ 
    if(!List2.Contains(address)) 
    { 
     ret.Add(address); 
    } 
} 

以下是覆蓋可能適用於您的.Equals方法的示例。

class EmailAddress 
{ 
    public string Address { get; set; } 

    public override bool Equals(object o) 
    { 
     EmailAddress toCheck = o as EmailAddress; 
     if(toCheck == null) return false; 
     // obviously this is a bit contrived, but you get the idea 
     return (this.Address == toCheck.Address); 
    } 

    // override GetHashCode as well when overriding Equals 
} 
+0

如果List2包含List1中的EmailAddress,仍然會將其添加到此方案中。無論出於何種原因,Contains()方法無法按預期工作。 – Brandon 2010-06-23 20:15:15

+0

這是因爲你沒有覆蓋.Equals方法,所以你正在檢查引用,而不是值。 – 2010-06-23 20:26:58

+0

我不知道我會怎麼做來實現重寫的.Equals方法,但至少在檢查引用部分是有意義的。 – Brandon 2010-06-23 20:38:11

0
 List<String> list1 = new List<string>(); 
     List<String> list2 = new List<string>(); 
     List<String> list3 = list1.Except(list2).ToList();