При использовании Contains в очереди массивов консоль возвращает значение False. Почему?

1

Я создал программу, в которой у меня есть очередь массивов int:

Queue< int[] > Test = new Queue< int[] >();

Учитывая массив, я хочу проверить, находится ли массив внутри очереди.

В настоящее время я использую пространства имен: System, System.Collections и System.Collections.Generic.

Я попробовал что-то вроде этого:

Queue<int[]> Test = new Queue<int[]>();

Test.Enqueue(new int[] { 20, 20 });

Console.WriteLine( Test.Contains(new int[] { 20, 20 }) ); // Is the array {20,20} inside the queue?

В этом коде мне кажется, что консоль выдаст "true", потому что я добавил массив {20, 20} в очередь, и теперь я проверяю использование метода Contains.

Но когда я запускаю код - консоль выводит false.

У меня есть два вопроса: почему это происходит? И как я могу это исправить?

  • 0
    чтобы сравнение работало со ссылками, необходимо создать средство сравнения на равенство или цикл по каждому массиву, вызвать SequenceEqual и передать этот новый массив для сравнения.
Теги:
arrays
contains
queue

3 ответа

3
Лучший ответ

Поскольку массивы являются ссылочными типами, сравнение будет основываться на ссылках. Даже если содержимое одного и того же, у ваших массивов есть разные ссылки. Вот почему вы ошибаетесь.

Чтобы исправить это, вы можете реализовать пользовательский сопоставитель или использовать методы LINQ например

bool arrayExists = Test.Any(x => x.SequenceEqual(new[] { 20, 20 }));
  • 0
    На правильном пути, но выделит новый массив для каждого теста.
  • 0
    да, этого можно избежать, создав массив из запроса.
1

Contains() использует тип сравнения по умолчанию. Для массивов сравнивается ссылка массива, а не содержимое. Вам нужно будет создать собственный сопоставитель сравнений.

Что-то вроде этого:

class ArrayComparer : IEqualityComparer<int[]>
{
    public bool Equals(int[] x, int[] y)
    {
        return x.SequenceEqual(y);
    }

    public int GetHashCode(int[] obj)
    {
        int h = 0;

        foreach (int item in obj)
        {
            h = (h << 5) + 3 + h ^ item.GetHashCode();
        }

        return h;
    }
}

Test.Contains(new int[] { 20, 20 }, new ArrayComparer())
0

По умолчанию массивы сравниваются по ссылке, а не по содержимому. Один из способов его устранения - хранить списки вместо массивов, которые будут сравнивать содержимое. Вы можете преобразовать свои массивы в списки перед добавлением в очередь и обратно, после того, как вытащить их, если это важно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню