C# List как ключ словаря

у меня есть словарь, который включается список:

private Dictionary<List<custom_obj>, string> Lookup;

Я пытаюсь использовать ContainsKey, но он, похоже, не работает, и я понятия не имею, почему. Вот отладочная информация из моего окна Visual Studio Immediate:

?Lookup.Keys.ElementAt(7)[0]
{custom_obj}
    Direction: Down
    SID: 2540
?Lookup.Keys.ElementAt(7)[1]
{custom_obj}
    Direction: Down
    SID: 2550
searchObject[0]
{custom_obj}
    Direction: Down
    SID: 2540
searchObject[1]
{custom_obj}
    Direction: Down
    SID: 2550
?Lookup.ContainsKey(searchObject)
false

в моем здравом смысле, что последний ContainsKey должен быть истинным. Надеюсь, я включил достаточно информации... есть идеи?

спасибо!

4 ответов


на List<custom_obj> экземпляр действует как ключ совершенно неравные экземпляр ссылается searchObject.

Если вы хотите, чтобы словарь использовал значения в списке вместо ссылочного равенства для поиска соответствующих ключей, вы должны указать IEqualityComparer в конструктор словаря (так как вы не можете переопределить Equals и GetHashCode в List<T>).


у вас есть две отдельные Lists, которые содержат те же элементы. Правильный способ узнать, равны ли два списка, - это SequenceEqual метод.

вы не можете по умолчанию делать то, что вы пытаетесь сделать. Однако вы можете написать custom IEqualityComparer и передать его в Dictionary конструктор.

вот образец generic IEqualityComparer:

class ListComparer<T> : IEqualityComparer<List<T>>
{
    public bool Equals(List<T> x, List<T> y)
    {
        return x.SequenceEqual(y);
    }

    public int GetHashCode(List<T> obj)
    {
        int hashcode = 0;
        foreach (T t in obj)
        {
            hashcode ^= t.GetHashCode();
        }
        return hashcode;
    }
}

вы можете улучшить GetHashCode реализация, так как это было быстрое и грязное решение.


Это будет работать, только если фактический экземпляр списка, используемый в поиске, совпадает с экземпляром, добавленным в качестве ключа. Он не будет сравнивать содержимое списка. Это то же самое поведение, которое вы получите, если попытаетесь сравнить два объекта списка напрямую.


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