2011-07-01 9 views
5

mam coś takiego:C# Użycie obiektu zamiast odniesienia dla List.Contains()

public class MyClass 
{ 
    public string Type { get; set; } 
    public int Value { get; set; } 
} 

a potem mam:

List<MyClass> myList = new List<MyClass>() 

// ... Populate myList 

if (myList.Contains("testType")) 
{ 
    // Do something 
} 

W powyższym kodzie, chcę myList.Contains() dopasować we właściwości Type zamiast odwołania do obiektu MyClass. Jak to osiągnąć? Czy używam interfejsu IComparable lub ICompare, czy mogę przesłonić MyClass.Equals(), czy też wystarczy, aby nadpisać ciąg od MyClass?

Edycja: Po wykonaniu kilku testów z nadrzędnymi Equals() i obsady ciąg MyClass, wykonawcze ICompare i IComparable, odkryłem, że żadna z tych metod nie działa. Właściwie wygląda na to, że zadziała, jeślibym zastąpił obsadkę w postaci MyClass, coś w rodzaju myList.Contains((MyClass)"testType"). Jednak myślę, że chciałbym odpowiedzieć na Scrum Meister jest lepiej :)

Odpowiedz

9

Można użyć metody Any rozszerzenia:

if (myList.Any(x => x.Type == "testType")) 
{ 
    // Do something 
} 
+0

hhmmm ... zdecydowanie prostsze niż ja;) PS: – IAbstract

+0

upewnij się, że dodajesz przy użyciu System.Linq; na górze pliku .cs - to potknęło mnie kilka razy :-) –

+0

Bardzo elegancki. To z pewnością trafi do mojej biblioteki kodów fragmentów kodu. Rzeczywiście uświadomiłem sobie, po opublikowaniu pytanie, że moje ciągi Type muszą być unikatowe na całej mojej liście, więc w końcu użyłem 'Dictionary ' zamiast. – Ozzah

0

przypadku zastosowania IEquatable<T>, będzie w zasadzie zastąpić metodę Object.Equals(). Według MSDN należy jawnie nadpisać metodę Object.Equals. Następnie można zrobić coś takiego:

void Add (MyClass testCls) 
{ 
    var myCls = myList.Where(x => x.Equals(testCls)).Select(x => x).FirstOrDefault(); 

    if (myCls == null) 
    { 
      // then myList does not contain the object you want to add 
      myList.Add(testCls); 
    } 
} 

Więcej o IEquatable<T>: MSDN IEquatable(T)
Zaletą jest to, że jesteś rzeczywiście sprawdzanie przeciwko mieniu innych treści lista Type - jeśli to, czego szukasz, aby zrobić .

0

Aby wyjaśnić odpowiedź The Scrum Meister, podany warunek nie zostanie skompilowany, jeśli poprawnie go przeczytam. Widzisz, czy lista zawierająca obiekty MyClass zawiera ciąg, więc to nie zadziała.

Wygląda na to, co naprawdę chcesz zrobić, to sprawdzić i sprawdzić, czy jakakolwiek instancja obiektu MyClass znajdująca się na tej liście ma właściwość Typ, która pasuje do żądanego typu.

Dla jasności, choć bym ponownie zdefiniować klasę MyClass tak:

public class MyClass { 
    public Type MyType { get; set; } 
    public int Value { get; set; } 
} 

Wtedy twój stan będzie:

if(myList.Any(x => x.MyType == typeof(SomeClass)) { // put the real class name in the typeof() 
    // Do something 
} 

nadzieję, że wyjaśnia rzeczy nieco jaśniejsze.

+0

Mój "Typ" nie jest typem C# ...jest to typ pracownika, który czytam z pliku CSV, na przykład "Handel detaliczny", "Wsparcie" lub "Konta". Nie wiem, czy to ma wpływ na twoją sugestię? – Ozzah

+0

Ach, rozumiem. Po prostu preferuję czytelność konwersji typu. Jeśli musisz pobrać typ z łańcucha, możesz użyć 'Type t = Type.GetType (String typename)' –

3

W dodatkowy do odpowiedzi @The Scrum Meister, o ile używasz C# 2.0 można użyć List<T>.Find

MyClass target = myList.Find(m => m.Type == "testType"); 
if (target != null) 
{ 
    // Do something to the target 
} 
Powiązane problemy