Вопрос по c#, list, containskey, dictionary – C # Список как словарь ключ

16

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

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

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

<code>?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
</code>

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

Спасибо!

Ваш Ответ

4   ответа
10

У вас есть два отдельныхListы, которые содержат одинаковые элементы. Правильный способ узнать, равны ли два списка, с помощьюSequenceEqual метод.

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

Вот образец общего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 реализация, так как это было быстрое и грязное решение.

GetHashCode пропускает возврат.
Ты можешь использоватьStructuralComparisons класс (начиная с .NET 4.0 и Visual Studio 2010), см.this answer.
Краткое примечание. Как подсказывает ответ, вы не должны использовать этот Comparer. Метод equals чувствителен к порядку, а метод hash - нет.
3

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

16

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

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

0

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

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