Словарь C#, дающий KeyNotFoundException, не знаю почему
Я программист-любитель, и это кажется простой проблемой для решения, но я просто не могу понять, как. Ниже приведен код C#, который не работает так, как я хочу. Я ожидаю, что это вернет 3, но вместо этого бросает KeyNotFoundException
, Списки одинаковы, поэтому не должно ли возвращаться 3? Спасибо за любую помощь.
Dictionary<object, double> dict = new Dictionary<object, double>();
dict.Add(new List<object>() { "a", "b" }, 3);
double output = dict[new List<object>() { "a", "b" }];
3 ответа
List<T>
является ссылочным типом без специального Equals
реализация. Итак, в вашем случае, хотя оба экземпляра вашего списка имеют одинаковое содержимое, они все равно являются разными экземплярами и, как таковые, не считаются равными при поиске ключа.
В зависимости от ваших потребностей вы можете использовать разные решения:
Если в вашем списке всегда одинаковое количество предметов, вы можете использовать Tuple:
Dictionary<Tuple<string, string>, double> dict = new Dictionary<Tuple<string, string>, double>(); dict.Add(Tuple.Create("a", "b"), 3); double output = dict[Tuple.Create("a", "b")];
Если количество элементов отличается, вы можете создать свой собственный список, который сравнивает его содержание.
Оба списка являются отдельными экземплярами, поэтому ReferenceEquals
возвращается false
, но это используется по умолчанию. Вы могли бы реализовать кастом IEqualityComparer<IList<object>>
для конструктора словаря:
public class ListComparer : IEqualityComparer<IList<object>>
{
public bool Equals(IList<object> x, IList<object> y)
{
if (x == null || y == null) return false;
return x.SequenceEqual(y);
}
public int GetHashCode(IList<object> list)
{
if (list == null) return int.MinValue;
int hash = 19;
unchecked // Overflow is fine, just wrap
{
foreach (object obj in list)
if(obj != null)
hash = hash + obj.GetHashCode();
}
return hash;
}
}
Теперь все работает как положено:
var dict = new Dictionary<List<object>, double>(new ListComparer());
dict.Add(new List<object>() { "a", "b" }, 3);
double output = dict[new List<object>() { "a", "b" }]; // 3.0