c# - KeyNotFoundException : 给定的键不在字典中
问题描述
KeyNotFoundException
每当我尝试访问字典中的键时,我都会收到。
我有一个PricingRules
有字典的类:
public class PricingRules
{
Dictionary<ItemCode, Money> pricing_rules;
public PricingRules()
{
pricing_rules = new Dictionary<ItemCode, Money>();
pricing_rules.Add(new ItemCode("A"), new Money(50));
pricing_rules.Add(new ItemCode("B"), new Money(30));
pricing_rules.Add(new ItemCode("C"), new Money(20));
pricing_rules.Add(new ItemCode("D"), new Money(15));
}
public void itemScanned(ItemCode itemCode, Money amount)
{
amount.Add(pricing_rules[itemCode]);
}
public Money AmountForItem(ItemCode itemCode)
{
return pricing_rules[itemCode];
}
}
字典中的键是类型ItemCode
:
public class ItemCode
{
private readonly string itemCode;
public ItemCode(string itemCode)
{
this.itemCode = itemCode;
}
public override int GetHashCode()
{
return itemCode.GetHashCode();
}
}
并且值是类型Money
:
public class Money
{
private int amount;
public Money(int amount)
{
this.amount = amount;
}
public override bool Equals(object obj)
{
Money money = (Money)obj;
return this.amount == money.amount;
}
public void Add(object obj)
{
Money money = (Money)obj;
this.amount += money.amount;
}
public override int GetHashCode()
{
return amount.GetHashCode();
}
}
我已经尝试覆盖GetHashCode()
函数以返回类中原始类型的 HashCode 但它仍然给出KeyNotFoundException
我写的测试是:
public class PricingRulesShould
{
[Fact]
void ReturnValueFiftyWhenKeyIsA()
{
Money expected = new Money(50);
PricingRules pr = new PricingRules();
ItemCode itemcode = new ItemCode("A");
Money actual = pr.AmountForItem(itemcode);
Assert.Equal(expected, actual);
}
}
解决方案
当Dictionary
访问它的元素时,它会寻找键的相等性。
由于ItemCode
不是原始类型,因此在比较new ItemCode("A") == new ItemCode("A")
时应该得到false
结果,因为它们是具有相同内容的不同实例。
你可以做的是IEquatable<ItemCode>
通过ItemCode
类来实现:
public class ItemCode : IEquatable<ItemCode>
{
private readonly string itemCode;
public ItemCode(string itemCode)
{
this.itemCode = itemCode;
}
public override int GetHashCode()
{
return itemCode != null ? itemCode.GetHashCode() : 0;
}
public bool Equals(ItemCode other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return string.Equals(itemCode, other.itemCode);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj is ItemCode ic && Equals(ic);
}
}
推荐阅读
- r - 如何生成随机数据以在 R Markdown 的一个样本 t 检验中使用?
- java - 错误的输出来自 JNA 中的结构字段值
- google-apps-script - 谷歌脚本将元素附加到 HTML 文档
- r - 如何从矩阵中提取 2 个成对向量?
- .net - 为什么 DataSet.WriteXml 偶尔会将 NUL 字节写入文件?可以预防吗?
- postgresql - PostgreSQL - 在没有警告的情况下创建扩展
- c# - ef核心插入具有导航属性的实体列表
- windows - 是否可以将此多行批处理脚本转换为可工作的单行脚本?
- wso2is - 通过单个应用程序的外部 IDP 在 WSO2 API 管理器中实现单点登录
- c# - 如何首先调用类验证属性而不是属性验证属性C#