2012-03-29 62 views
3

我很奇怪,爲什麼當我嘗試不加我的對象列表中時,它的複製,它仍然將它添加C#列表中的重複

if (thePreviousList.Contains(thePreviousItem)) 
{ 
} 
else 
{ 
    thePreviousList.Add(thePreviousItem); 
} 

例如thepreviousitem ID = 1,名稱=測試 如果我有另一個對象具有相同的ID和相同的名稱它仍然會添加它...

+0

也許你想使用詞典('TKEY的,TValue)',而不是名單 – 2012-03-29 15:24:00

回答

4

如果你不想重載Equals,你可以使用LINQ來檢查是否使用相同的ID和名稱的對象(這不一定相同對象)已經存在:

if (thePreviousList.Any(item => item.ID == thePreviousItem.ID 
          && item.Name == thePreviousItem.Name)) 
{ 
} 
else 
{ 
    thePreviousList.Add(thePreviousItem); 
} 
5

您需要正確實施Equals方法對您試圖添加到列表中的對象。要確定列表是否已包含傳遞的對象,Contains方法使用的是Equals

+0

我能做些什麼,然後以不添加對象列表中是否有重複?沒有使用equals方法? – Kiwimoisi 2012-03-29 15:21:19

+3

爲什麼你不想使用'Equals'方法?這是最簡單的事情。 – 2012-03-29 15:23:31

+0

@Emged您可以使用不會接受重複的集合(即集合,例如HashSet )並提供比較器,也可以編寫自己的Contains方法來搜索列表以查找使用自定義比較器的項目。 – Servy 2012-03-29 15:26:50

1

因爲List<>.Contains正在檢查引用不檢查列表中的對象的屬性。

爲了達到此目的,您應該覆蓋Equals,對於最佳做法,也可以覆蓋GetHashCode。規則應該是當Equals返回true時,應該返回相同的散列碼。

類似以下內容對您來說應該足夠了:

public override bool Equals(object obj) 
{ 
    var i = obj as YourType; 
    if(i == null) return false; 

    return i.Id == this.Id && i.Name == this.Name; 
} 

public override int GetHashCode() 
{ 
    return this.Id.GetHashCode()^this.Name.GetHashCode(); 
} 
+0

那麼如果有重複的話,不要在列表中添加對象,我該怎麼辦? – Kiwimoisi 2012-03-29 15:20:38

+1

@Emged - 查看更新(儘管我在下面看到您的評論關於不使用Equals - 這總是讓我感到困惑......您爲什麼還想用除* right *之外的其他方式做點什麼?) – Jamiec 2012-03-29 15:23:28

4

從文檔:

該方法通過使用默認的相等比較確定的平等,由對象的實現IEquatable的定義(Of T).T的等式方法(列表中值的類型)。

如果您還沒有實施IEquatable<T>.Equals,它使用默認的引用相等。或者,您實現了IEquatable<T>.Equals,但沒有正確執行。

例如thepreviousitem ID = 1,名稱=測試,如果我有相同的id和另一個同名的對象仍然會增加它...

你需要像

class Foo : IEquatable<Foo> { 
    public int Id { get; private set; } 
    public string Name { get; private set; } 
    public Foo(int id, string name) { 
     this.Id = id; 
     this.Name = name; 
    } 
    public bool Equals(Foo other) { 
     return this.Id == other.Id && this.Name == other.Name; 
    } 
} 

最後,如果檢查重複項是你將要做的很多事情,那麼你不應該使用List<T>。你應該使用HashSet<T>

+0

您不一定需要爲了實現'IEquatable ',覆蓋'Equals'就足夠了,因爲如果沒有實現IEquatable <>',默認比較器會調用Equals。 – 2012-03-29 15:32:16

2

這聽起來從您對其他答案的意見,你不想覆蓋Equals

可以代替做到這一點:

if (thePreviousList.Any(item => thePreviousItem.id == item.id && thePreviousItem.name == item.name)) 
{ 

} 
else 
{ 
    thePreviousList.Add(thePreviousItem); 
}