Здравствуйте.
Имеется коллекция _data (Dictionary), где ключем выступает массив типа int[], а значением является условный тип.
private static Dictionary<int[], SomeType> _data = new Dictionary<int[], SomeType>();
Я добавил в коллекцию какие то данные, например так:
_data.Add(new int[2] { 1, 2 }, new SomeType(p1, p2));
Но при получении значений возникла проблема, если написать:
_data.ContainsKey(new int[2] { 1, 2 });
То всегда будет false. Я так понял потому что инициализирую все время новый массив, а не даю ссылку на него. Сам вопрос заключается в том, как лучше и проще всего в данном случае оперировать с набором данных как ключем. Я только изучаю этот прекрасный язык, недавно почитав о структурах, понял что может быть их лучше использовать в данном случае, но все таки хотел узнать у опытных программистов.
Вы правы, получить данные не удается, потому что ваш ключ ссылочного типа, и вы всегда создаете новый объект, вместо того чтобы использовать ссылку на оригинальный.
В тех случаях, когда вы нигде не храните ссылки на оригинальные объекты, удобнее использовать в качестве ключей значимые типы или строки. Например - вот так:
private string GetKey(params int[] values) {
return string.Join("_", values);
}
_data.Add(GetKey(1, 2), new SomeType(p1, p2));
В таком случае вы в любое сможете получить ключ, нигде не храня его.
Использовать ссылки на объекты в качестве ключей удобно только тогда, когда эти объекты у вас где-то еще "работают", и время от времени возникает необходимость получить информацию, имея на руках ссылку на такой объект. Судя по коду, ваша программа устроена не так.
Дело в том, что Dictionary<TKey, TValue> использует GetHashCode. Класс Array не переопределяет этот метод, а значит используется реализация класса System.Object. Под капотом вызывается нативный метод CLR ObjectNative::GetHashCode, который делает что-то, чего никто не знает. Но факт в том, что одинаковые объекты имеют разный хеш код, если они находятся по разным адресам. Вот пример:
int[] x1 = new[] { 1, 2 };
int[] x2 = new[] { 1, 2 };
Console.WriteLine(x1.GetHashCode());
Console.WriteLine(x2.GetHashCode());
Выводит:
46104728
12289376
Dictionary<TKey, TValue> в первую очередь сравнивает хеш-коды, а потом уже пытается сравнить объекты.
Для вашей задачи нужно создать класс, который будет содержать внутри себя массив, переопределить в нем GetHashCode и метод Equals. А еще лучше реализовать интерфейс IEquatable. Как правильно реализовать GetHashCode - отдельный вопрос. Можно например "скопипастить" GetHashCode из класса System.String, который уж точно реализован отлично:
class MyArray : IEquatable<MyArray>
{
private int[] _array;
public MyArray(int[] array)
{
this._array = array;
}
public override int GetHashCode()
{
int num = 5381;
int num2 = num;
for (int i = 0; i < _array.Length; i += 2)
{
num = ((num << 5) + num ^ _array[i]);
if (i + 1 == _array.Length)
break;
num2 = ((num2 << 5) + num2 ^ _array[i + 1]);
}
return num + num2 * 1566083941;
}
// Equals и др.
}
Теперь вам вместо ключа int[] нужно использовать экземпляры MyArray.
int[] x1 = new[] { 1, 2 };
int[] x2 = new[] { 1, 2 };
var a1 = new MyArray(x1);
var a2 = new MyArray(x2);
Console.WriteLine(a1.GetHashCode());
Console.WriteLine(a2.GetHashCode());
Такой код теперь покажет одинаковые хеш-коды:
-1776415353
-1776415353
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники