Nie było, nie ma i może nie być, przynajmniej w to uwierzę. Przyczyną takiego stanu rzeczy jest prawdopodobnie zachowanie zdefiniowane przez użytkownika.
Elementy w kolekcjach nie powinny znajdować się w określonej kolejności, chociaż mają naturalnie uporządkowanie, nie na tym powinny polegać algorytmy porównujące. Załóżmy, że masz dwie kolekcje:
{1, 2, 3, 4}
{4, 3, 2, 1}
Czy są równi czy nie? Musisz wiedzieć, ale nie wiem jaki jest twój punkt widzenia.
Kolekcje są domyślnie nieuporządkowane koncepcyjnie, dopóki algorytmy nie zapewnią reguł sortowania. Ta sama rzecz, na którą zwraca uwagę serwer SQL, podczas próby podziału na strony, wymaga podania reguł sortowania:
https://docs.microsoft.com/en-US/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-2017
Kolejne dwie kolekcje:
{1, 2, 3, 4}
{1, 1, 1, 2, 2, 3, 4}
Znów są równe czy nie? Ty mi powiedz ..
Powtarzalność elementów kolekcji odgrywa swoją rolę w różnych scenariuszach, a niektóre kolekcje, takie jak Dictionary<TKey, TValue>
, nawet nie zezwalają na powtarzające się elementy.
Uważam, że tego rodzaju równość jest definiowana przez aplikację, dlatego ramy nie zapewniły wszystkich możliwych implementacji.
Cóż, w ogólnych przypadkach Enumerable.SequenceEqual
jest wystarczająco dobry, ale zwraca false w następującym przypadku:
var a = new Dictionary<String, int> { { "2", 2 }, { "1", 1 }, };
var b = new Dictionary<String, int> { { "1", 1 }, { "2", 2 }, };
Debug.Print("{0}", a.SequenceEqual(b)); // false
Przeczytałem niektóre odpowiedzi na takie pytania (możesz je znaleźć w Google ) i ogólnie, czego bym użył:
public static class CollectionExtensions {
public static bool Represents<T>(this IEnumerable<T> first, IEnumerable<T> second) {
if(object.ReferenceEquals(first, second)) {
return true;
}
if(first is IOrderedEnumerable<T> && second is IOrderedEnumerable<T>) {
return Enumerable.SequenceEqual(first, second);
}
if(first is ICollection<T> && second is ICollection<T>) {
if(first.Count()!=second.Count()) {
return false;
}
}
first=first.OrderBy(x => x.GetHashCode());
second=second.OrderBy(x => x.GetHashCode());
return CollectionExtensions.Represents(first, second);
}
}
Oznacza to, że jedna kolekcja reprezentuje drugą w swoich elementach, w tym wielokrotnie powtarzanych, bez uwzględnienia pierwotnego porządku. Niektóre uwagi dotyczące wdrożenia:
GetHashCode()
służy tylko porządkowi, a nie równości; Myślę, że w tym przypadku wystarczy
Count()
tak naprawdę nie wyliczy kolekcji i bezpośrednio wpisze się w implementację właściwości ICollection<T>.Count
Jeśli referencje są równe, to tylko Boris
IList
? Pytanie jest dwuznaczne.