Поиск в словаре C # с использованием производного класса - PullRequest
0 голосов
/ 01 апреля 2019

Я думаю, что это может быть общий вопрос, но я не смог найти ни одного поста об этом.

Я пишу псевдокод ниже. Если вы хотите скомпилировать код, просто проигнорируйте этот пост.

Так сказать, два класса: один базовый класс и один дочерний класс. ПРИМЕЧАНИЕ. Оба класса имеют функции переопределения Equals () и GetHashCode () для обеспечения равенства с одним и тем же свойством.

public class A // A has a string property of name
public class B:A // B has a string property of title

var a = new A{name = "bob"};
var b = new B{name = "bob", title = "em"};

В некоторых кодах есть словарь, основанный на A

var dict = new Dictionary<A>();

Делая какие-то добавления, например,

dict.Add(a);

Однако функция поиска вызовет KeyNotFoundException, если я использую поиск производного класса с приведением типа / o

dict[b];

Словарь вычислит хэш-код B вместо A и выдает исключение в соответствии с этим.

Простое и неудобное решение - создать новый экземпляр A на основе свойства B.

dict[new A{name = b.name}];

Интересно, есть ли лучшее решение?

Ответы [ 2 ]

0 голосов
/ 01 апреля 2019

Попробуйте создать EqualityComparer и передать его экземпляр в конструктор словаря.

class AEqualityComparer : IEqualityComparer<A>
{
    public bool Equals(A x, A y)
    {
        return x.Equals(y);
    }

    public int GetHashCode(A obj)
    {
        return obj.GetHashCode();
    }
}

var dict = new Dictionary<A, object>(new AEqualityComparer());
0 голосов
/ 01 апреля 2019

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

Если вы сделаете это:

dict.Add(new A{name = "bob"}, someData);

и затем сделайте это

var result = dict[new A{name = "bob"}];

вы получите «ключ не найден», потому что два новых A - это разные объекты.

...