Допустим, есть класс, у которого есть 2 цифровых поля.
Хотелось бы эти 2 поля сделать первичным ключем в Dictionary.
В будущем этот ключ будет использоваться для поиска совпавших значений между 2 мя словарями.
Как это можно сделать, что бы не потерять в производительности?
У меня была идея, хранить их как строку, но может быть есть решение лучше?
P.S
Dictionary использую из-за высокой скорости поиска по ключу.
К моему удивлению, DataTable оказался тормознутее=( на 20к строк
Как один из вариантов
Можно использовать класс Tuple. Например Dictionary<Tuple<T1,T2>, T3>
,
где T1, T2, T3 значения любых типов. В Tuple
сравниваться будет по
внутренним значениям.
у Tuple переопределены методы GetHashCode и Equals © Grundy
IEqualityComparer<T>
в конструктор, где Т - тип ключа. Сравнение будет производиться с использованием компаратора.Есть несколько путей использовать составной ключ для Dictionary (аналогично для HashSet)
Использовать структуру. Правила сравнения структур таковы, что сравниваются значения всех полей, а не ссылки на объекты.
Использовать класс с переопределенными методами Equals
, GetHashCode
. Это позволит использовать для вычисления хэша не все поля класса, а только нужные.
Использовать класс реализующий IEquatable<T>
Использовать при создании словаря перегрузку конструктора принимающую IEqualityComparer<T>
Привношу пример кода из дублирующего вопроса.
Классу Dictionary
для того, чтобы обращаться к элементу по ключу, надо сравнивать ключи друг с другом.
Поэтому необходимо реализовать операцию сравнения двух объектов составного ключа, например, реализовав интерфейс IEquatable<ComplexKey>
и переопределив метод object.Equals
и object.GetHashCode
.
Пример реализации IEquatable и переопределения Equals
и GetHashCode
:
public class ComplexKey : IEquatable<ComplexKey>
{
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<int>.Default.Equals(value1, other.value1)
&& EqualityComparer<string>.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<int>.Default.GetHashCode(value1);
result = 31 * result + EqualityComparer<string>.Default.GetHashCode(value2);
}
return result;
}
}
Методы Equal
просто сравнивают попарно все значения составного ключа и возвращают true
только тогда, когда все поля класса совпадают.
Метод GetHashCode
считает значение хеша способом, который на SO набрал больше всего плюсов.
Вероятно, Tuple
подойдёт для использования в качестве ключа.
Хочу убить процесс, но так получается что убиваются процессы в имени которых только одно слово, если два то не выходитК примеру: этот процесс...
Господа, пытаюсь сделать получение JWT токена на аккаунте с включенным Two-factor authentication (2fa)Как я это сделал:
Пытаюсь освоить xamarin как было бы грамотнее реализовать расположение компонентов на activity так как на картинкепримечание компоненты генерируются...