2016-07-26 62 views
0

不能找到一個簡單的答案。我的問題是我想的對象的值進行比較,在列表中的一個對象的價值...設置一個簡單的iequatable類c#

我的課:

public class MatchList 
    { 
     public int SomeInt { get; set; } 
     public decimal SomeDecimal { get; set; } 
    } 

創建theMatchList。看來我只能比較的對象,而不是值與對象theMatchList.Contains ......「

      MatchList ML = new MatchList(); 

          ML.SomeInt = 12; 
          ML.SomeDecimal = 2.3; 
          if (theMatchlist.Contains(ML)) 
          { 
           DoSomething; 
          } 

如何獲得火「DoSomething的」?假設'theMatchList'中有一個條目分別等於12和2.3。我知道這與iequatable有關,但我不太明白這是如何工作的。提前致謝!

+0

後綴的東西'List'意味着它包含的項目列表。但是你的定義似乎只包含2個標量值。所以我很困惑你的問題 - 是'MatchList'列表?列表中的項目看起來像什麼?通常,列表應該是「IEnumerable」或「IList」。你的'MatchList'不包含'Contains'的定義。代碼中的'theMatchList'是什麼?你的問題引發了更多的問題。 – Jamiec

+0

是'列表'類型的'theMatchlist'? – sebingel

回答

1

你的命名是有點不清楚,我認爲你確實有,你想找到一個特定的MatchList(我建議重新命名MatchList至少在這種情況下,且優選的更具描述性的MatchItem)一List<MatchList>

然後從List<T>.Contains文檔:

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

所以,你將必須實現IEquatable<T>爲你的類。此外,該建議是

[我] F你實現equals,你也應該重寫的Object.Equals(對象)和GetHashCode的基類的實現,使他們的行爲與該IEquatable一致。等於方法。

如果您實現GetHashCode,則其結果不應在對象的生命週期中發生變化。在大多數情況下,使類不變是足夠的。如果您需要更新字段,則需要以不同方式實施GetHashCode

因此,所有的一切,如果你想使用Contains類最終會看起來像下面的東西:

public class MatchList : IEquatable<MatchList> 
{ 
    // Note: Fields are readonly to satisfy GetHashCode contract 
    private readonly int someInt; 
    private readonly decimal someDecimal; 

    // Public constructor creates immutable object 
    public MatchList(int myInt, decimal myDecimal) 
    { 
     this.someInt = myInt; 
     this.myDecimal = myDecimal; 
    } 

    // Properties are now read-only too. 
    public int SomeInt { get { return this.someInt; } } 
    public decimal SomeDecimal { get { return this.someDecimal; } } 

    // Implementation of IEquatable<MatchList> 
    public bool Equals(MatchList other) 
    { 
     return (other != null) 
      && (this.SomeInt == other.SomeInt) 
      && (this.SomeDecimal == other.SomeDecimal); 
    } 

    // Override of Object.Equals 
    // Calls the IEquatable.Equals version if possible. 
    public override bool Equals(object obj) 
    { 
     return (obj is MatchList) && this.Equals(obj as MatchList); 
    } 

    public override int GetHashCode() 
    { 
     return (this.someInt * 17)^this.someDecimal.GetHashCode(); 
    } 
} 
+0

你應該在'Equals(MatchList other)'中檢查'null'。而'^'(xor)而不是'+'會產生更好的散列函數。 –

+0

謝謝@EliArbel,更新。由於'GetHashCode',這個類也是不可變的。 – CompuChip

+0

每次我需要'IEquatable'時,結果都比我想象的要多得多。 – CompuChip

0

正如我評論,你的問題是不太清楚,所以我會盡我所能解釋這個概念。

這很可能是你所想要的代碼是列表不是項目列表本身:

public class MatchItem : IEquatable<MatchItem> 
{ 
    public int SomeInt { get; set; } 
    public decimal SomeDecimal {get; set; } 

    public bool Equals(MatchItem item) 
    { 
     if(item == null) 
      return false; 

     return this.SomeInt == item.SomeInt && this.SomeDecimal == item.SomeDecimal; 
    } 

    // You should also override object.ToString, object.Equals & object.GetHashCode. 
    // Omitted for brevity here! 
} 

你會注意到,有IEquatable<MatchItem>實現這使得它能夠被比較MatchItem的其他實例。

此後,該代碼將工作:

var items = new List<MatchItem>() 
{ 
    new MatchItem{SomeInt = 1, SomeDecimal = 0.3M}, 
    new MatchItem{SomeInt = 12, SomeDecimal = 2.3M} 
}; 

var searchItem = new MatchItem{SomeInt = 1, SomeDecimal = 0.3M}; 

Console.WriteLine(items.Contains(searchItem)); // true 

工作例如:http://rextester.com/ZWNC6890