2012-02-14 19 views
9

System.Collections.GenericのListクラスを操作する場合、ContainsやIndexOfなどのメソッドは、IEquatableから実装されたEqualsメソッドまたはObjectクラスから提供されるオーバーライドされたEqualsメソッドのいずれかを使用して、渡された参照のオブジェクトを比較します。 Object.Equalsがオーバーライドされていない場合、渡された参照が自身と同じオブジェクトを指しているかどうかをチェックします。比較する?

私の質問は、Equalsがオーバーライドされた場合、Listを参照で比較する方法はありますか? のコードは、以下のリストから項目を削除します:

class Program 
{ 
    static void Main(string[] args) 
    {  
     var s1 = new SomeClass() { A = 5 }; 
     var s2 = new SomeClass() { A = 5 }; 
     var list = new List<SomeClass>(); 
     list.Add(s1); 
     list.Remove(s2); // s1 will get removed, even though s2 has been 
         // passed, because s1's Equals method will return true. 

    } 
} 

class SomeClass 
{ 
    public int A { get; set; } 

    public override bool Equals(object obj) 
    { 
     SomeClass s = obj as SomeClass; 
     if (s == null) 
     { 
      return false; 
     } 
     else 
     { 
      return s.A == this.A; 
     } 
    } 
} 

のは、私は対等の工assの実装を削除することができないんだとしましょう、参照の代わりに、値によって比較リストを作る方法はありますか?

答えて

13

List.RemoveAllを使用して、述語にObject.ReferenceEqualsという項目を比較することができます。

list.RemoveAll(item => object.ReferenceEquals(item, s2)); 

Visual Studio 2010 Expressからデバッグするときにコードが正常に1項目を削除しました。

+0

ありがとう、それはうまくいくようです。 – haiyyu

4

オースティンのソリューションはシンプルで機能します。しかし、ここには2つの一般的な拡張メソッドもあります:

items.RemoveAllByReference(item); 

public static void RemoveAllByReference<T>(this List<T> list, T item) 
{ 
    list.RemoveAll(x=> object.ReferenceEquals(x, item)); 
} 

public static bool RemoveFirstByReference<T>(this List<T> list, T item) 
{ 
    var index = -1; 
    for(int i = 0; i< list.Count; i++) 
     if(object.ReferenceEquals(list[i], item)) 
     { 
      index = i; 
      break; 
     } 
    if(index == -1) 
     return false; 

    list.RemoveAt(index); 
    return true; 
} 
+0

興味深いですが、これはなぜより最適です - これは述語が内部的に行うことと似ていませんか?あなたの推論を知りたいのと同じように... –

+0

アイテムがリストにn回ある場合はどうなりますか? –

+0

オースティンのメソッドは常にすべての要素をチェックします。これはループが見つかるとループを壊します。しかし、今考えてみると、リスト全体を検索し、リスト内の同じアイテムのすべてのインスタンスを削除する方が正しいかもしれません...だから、それはあなたが望むものに依存します。しかし、あなたが複数の場所でそれを使うならば、拡張メソッドは利点です。 – doblak

関連する問題