#c_sharp #net
Допустим, есть класс, у которого есть 2 цифровых поля. Хотелось бы эти 2 поля сделать первичным ключем в Dictionary. В будущем этот ключ будет использоваться для поиска совпавших значений между 2 мя словарями. Как это можно сделать, что бы не потерять в производительности? У меня была идея, хранить их как строку, но может быть есть решение лучше? P.S Dictionary использую из-за высокой скорости поиска по ключу. К моему удивлению, DataTable оказался тормознутее=( на 20к строк
Ответы
Ответ 1
Как один из вариантов Можно использовать класс Tuple. Например Dictionary, T3>, где T1, T2, T3 значения любых типов. В Tuple сравниваться будет по внутренним значениям. у Tuple переопределены методы GetHashCode и Equals © Grundy Использовать структуру, т.к. у структур идет сравнение по всем имеющимся полям Передавать IEqualityComparer в конструктор, где Т - тип ключа. Сравнение будет производиться с использованием компаратора. Ответ 2
Есть несколько путей использовать составной ключ для Dictionary (аналогично для HashSet) Использовать структуру. Правила сравнения структур таковы, что сравниваются значения всех полей, а не ссылки на объекты. Использовать класс с переопределенными методами Equals, GetHashCode. Это позволит использовать для вычисления хэша не все поля класса, а только нужные. Использовать класс реализующий IEquatableИспользовать при создании словаря перегрузку конструктора принимающую IEqualityComparer Ответ 3
Привношу пример кода из дублирующего вопроса. Классу Dictionary для того, чтобы обращаться к элементу по ключу, надо сравнивать ключи друг с другом. Поэтому необходимо реализовать операцию сравнения двух объектов составного ключа, например, реализовав интерфейс IEquatableи переопределив метод object.Equals и object.GetHashCode. Пример реализации IEquatable и переопределения Equals и GetHashCode: public class ComplexKey : IEquatable { private int value1; private string value2; public ComplexKey(int value1, string value2) { this.value1 = value1; this.value2 = value2; } public bool Equals(ComplexKey other) { return EqualityComparer .Default.Equals(value1, other.value1) && EqualityComparer .Default.Equals(value2, other.value2); } public override bool Equals(object other) { if (other is ComplexKey) return Equals((ComplexKey)other); return false; } public override int GetHashCode() { var result = 17; unckecked { result = 31 * result + EqualityComparer .Default.GetHashCode(value1); result = 31 * result + EqualityComparer .Default.GetHashCode(value2); } return result; } } Методы Equal просто сравнивают попарно все значения составного ключа и возвращают true только тогда, когда все поля класса совпадают. Метод GetHashCode считает значение хеша способом, который на SO набрал больше всего плюсов. Ответ 4
Вероятно, Tuple подойдёт для использования в качестве ключа.
Комментариев нет:
Отправить комментарий