C # Словарь массивов - PullRequest
5 голосов
/ 26 мая 2010

Могу ли я использовать C # Dictionary на таких классах, как массивы ??

Dictionary<double[],double[]>

Боюсь, что он не сможет сказать, когда массивы равны ...

EDIT:
Будет ли метод хеширования в словаре хорошо заботиться о массивах? или просто хешируете свои ссылки?

Ответы [ 3 ]

5 голосов
/ 26 мая 2010

Для ключей массива словарь будет использовать ссылки для хеширования и равенства, что, вероятно, не то, что вам нужно. Это оставляет вам два варианта: реализовать класс-оболочку для double[] или (лучше) написать что-нибудь, реализующее IEqualityComparer, и передать его конструктору Dictionary<T, T>.

3 голосов
/ 26 мая 2010

Будут сравниваться только ссылки на массивы. В следующем примере словарь будет иметь 2 записей, даже если массивы a и b имеют одинаковое количество записей, а значения записей равны:

double[] a = new[] { 1.0, 2.1, 3.2 };
double[] b = new[] { 1.0, 2.1, 3.2 };

Dictionary<double[], double[]> d = new Dictionary<double[], double[]>();

d[a] = new [] { 1.1 };
d[b] = new [] { 2.2 };

Console.WriteLine(d.Count);
Console.WriteLine(d[b][0]);
0 голосов
/ 26 мая 2010

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

Решением было бы заключить массив в класс, который будет хранить хеш-код до тех пор, пока данные не будут изменены, чтобы он не пересчитывался каждый раз:

class ArrayWrapper<T>
{
    private T[] _array;
    public ArrayWrapper(T[] array)
    {
        _array = array;
    }

    private int? _hashcode;
    public override int GetHashCode()
    {
        if (!_hashcode.HasValue)
        {
            _hashcode = ComputeHashCode();
        }
        return _hashcode.Value;
    }

    public override bool Equals(object other)
    {
        // Your equality logic here
    }

    protected virtual int ComputeHashCode()
    {
        // Your hashcode logic here
    }

    public int Length
    {
        get { return _array.Length; }
    }

    public T this[int index]
    {
        get { return _array[index]; }
        set
        {
            _array[index] = value;
            // Invalidate the hashcode when data is modified
            _hashcode = null;
        }
    }
}

Таким образом, ваш словарь будет Dictionary<ArrayWrapper<double>, ArrayWrapper<double>>. Конечно, вы можете захотеть добавить некоторые методы или свойства в оболочку (например, реализовать IList<T>)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...