2016-07-26 5 views
0

Cantは簡単な答えを見つけます。私の問題は私のクラス...私は、オブジェクトの値に、リスト内のオブジェクトの値を比較しようとしています簡単な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つのスカラー値を含んでいるようです。だから私はあなたの質問で混乱しています - 「マッチリスト」はリストですか?そのリスト内の項目は何のように見えるのですか?通常、リストは 'IEnumerable'または' IList'でなければなりません。あなたの 'MatchList'は' Contains'の定義を含んでいません。あなたのコードで 'theMatchList'とは何ですか?あなたの質問は非常に多くの質問を提起します。 – Jamiec

+0

'List 'の 'theMatchlist'はありますか? – sebingel

答えて

1

、私はあなたが実際にあなたが(私はそのような場合、より説明的好適なもので、少なくともMatchItemMatchListの名前を変更する提案)で、特定のMatchListを見つけたいList<MatchList>を持っていることを前提としています。 List<T>.Containsのドキュメントから次に

:TためIEquatable<T>.Equals方法(リスト中の値の型)のオブジェクトの実装によって定義されるよう

この方法は、既定の等値比較を使用して等価性を決定します。

あなたのクラスにはIEquatable<T>を実装する必要があります。また、アドバイスは

ということです彼らの行動は、IEquatableのそれと一致しているように、[i]は、あなたに等しいを実装fは、あなたもはObject.equals(Object)をとGetHashCodeメソッドの基本クラス実装をオーバーライドする必要があります。等しいメソッド。

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

関連する問題