Mam listę
List<MyObject> myList
i dodaję pozycje do listy i chcę sprawdzić, czy ten obiekt jest już na liście.
więc zanim to zrobię:
myList.Add(nextObject);
Chcę zobaczyć, czy nextObject jest już na liście.
Obiekt „MyObject” ma wiele właściwości, ale porównanie opiera się na dopasowaniu dwóch właściwości.
Jaki jest najlepszy sposób sprawdzenia przed dodaniem nowego „MyObject” do tej listy „MyObject”.
Jedynym rozwiązaniem, które wymyśliłem, było przejście z listy do słownika, a następnie uczynienie klucza połączonym ciągiem właściwości (wydaje się to trochę nieeleganckie).
Jakieś inne czystsze rozwiązania wykorzystujące listę lub LINQ lub coś innego?
Po prostu użyj metody Zawiera . Zauważ, że działa w oparciu o funkcję równości
Equals
źródło
Jeśli użycie tych dwóch właściwości jest możliwe do utrzymania, możesz:
źródło
Czy na pewno potrzebujesz listy w tym przypadku? Jeśli wypełniasz listę wieloma elementami, wydajność spadnie z
myList.Contains
lubmyList.Any
; czas wykonywania będzie kwadratowy. Warto rozważyć zastosowanie lepszej struktury danych. Na przykład,Możesz użyć HashSet w następujący sposób:
Oczywiście, jeśli ta definicja równości dla
MyClass
jest „uniwersalna”, nie musisz pisaćIEqualityComparer
implementacji; możesz po prostu zastąpićGetHashCode
iEquals
w samej klasie.źródło
Inną kwestią, o której warto wspomnieć, jest to, że powinieneś upewnić się, że Twoja funkcja równości jest zgodna z oczekiwaniami. Należy nadpisać metodę equals, aby ustawić, jakie właściwości obiektu muszą pasować, aby dwa wystąpienia były uznawane za równe.
Następnie możesz po prostu zrobić mylist.contains (item)
źródło
Oto szybka aplikacja konsoli, która przedstawia koncepcję rozwiązania problemu.
Cieszyć się!
źródło
Edycja: najpierw powiedziałem:
Co jest nieeleganckie w rozwiązaniu słownikowym. Wydaje mi się to całkowicie eleganckie, zwłaszcza że podczas tworzenia słownika wystarczy ustawić komparator.
Oczywiście nieeleganckie jest używanie czegoś jako klucza, gdy jest to również wartość.
Dlatego użyłbym HashSet. Jeśli późniejsze operacje wymagałyby indeksowania, utworzyłbym z niego listę po zakończeniu dodawania, w przeciwnym razie po prostu użyj skrótu.
źródło
Proste, ale działa
lub
źródło
Jeśli używasz EF core, dodaj
Przykład
źródło