Словарь <интервал [], bool> - сравнивают значения в массиве, не ссылку?

Я использую словарь для хранения идентификатора, otherID и значения bool. К сожалению, это сравнивает ссылку на массив, поэтому я не могу использовать его. Есть ли какой-либо путь, как иметь массив как ключ, но сравнить его значения вместо ссылки?Спасибо

6
задан Snake 7 January 2010 в 08:28
поделиться

4 ответа

Вы можете использовать свойство Comparer словаря, чтобы настроить его на пользовательский сравнитель, созданный вами.

EDIT: на самом деле это свойство доступно только для чтения, извините. Обязательно используйте соответствующий конструктор:

class IntArrayComparer : IEqualityComparer<int[]> {
    public bool Equals(int[] x, int[] y) {
        if (x.Length != y.Length) {
            return false;
        }
        for (int i = 0; i < x.Length; ++i) {
            if (x[i] != y[i]) {
                return false;
            }
        }
        return true;
    }
    public int GetHashCode(int[] obj) {
        int ret = 0;
        for (int i = 0; i < obj.Length; ++i) {
            ret ^= obj[i].GetHashCode();
        }
        return ret;
    }
}
static void Main(string[] args) {
    Dictionary<int[], bool> dict = new Dictionary<int[], bool>(new IntArrayComparer());
}
9
ответ дан 8 December 2019 в 13:46
поделиться

Вы можете попробовать реализовать IEqualityComparer, а затем передать экземпляр в соответствующий конструктор .

.
4
ответ дан 8 December 2019 в 13:46
поделиться

Это можно сделать двумя способами:

  • Создать сравнитель, реализующий IEqualityComparable, который вы передадите конструктору словаря.
  • Создать ключевой класс, инкапсулирующий целочисленный массив и реализующий IEquatable.
3
ответ дан 8 December 2019 в 13:46
поделиться

Нет ничего плохого в ответе Орсогуфо, но я хотел бы отметить, что если у вас есть .NET 3.5, Вы можете реализовать ArrayValueComparer с гораздо меньшим количеством кода, и в то же время сделать его универсальным, чтобы он мог сравнивать значения любого типа массивов, а не только целых массивов. Если на то пошло, вы можете легко заставить его работать с любым IEnumerable, а не только с массивами.

using System.Collections.Generic;
using System.Linq;

class ArrayValueComparer<T> : IEqualityComparer<T[]>
{
    public bool Equals(T[] x, T[] y)
    {
        return x.SequenceEqual(y, EqualityComparer<T>.Default);
    }

    public int GetHashCode(T[] obj)
    {
        return obj.Aggregate(0, (total, next) => total ^ next.GetHashCode());
    }
}

static void Main(string[] args)
{
    var dict = new Dictionary<int[], bool>(new ArrayValueComparer<int>());
}
1
ответ дан 8 December 2019 в 13:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: