You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

以自定义类为键时如何正确使用TryGetValue方法?关于Dictionary中TryGetValue参数的疑问

C# Dictionary<TKey, TValue> TryGetValue 方法的疑问解答

你的代码示例

var ambassadors = new Dictionary<CountryCode, Ambassador>();
Ambassador england = new Ambassador { CountryCode = new CountryCode("eng"), Name = "John", Age = 25 };
Ambassador australia = new Ambassador { CountryCode = new CountryCode("aus"), Name = "Martin", Age = 49 };
ambassadors.Add(england.CountryCode, england);
ambassadors.Add(australia.CountryCode, australia);
Console.WriteLine("Enter country code: ");
var code = Console.ReadLine();
if (ambassadors.TryGetValue(new CountryCode(code), out Ambassador ambassador))
{
    Console.WriteLine($"The ambassador is {ambassador.Name}");
}
else
{
    Console.WriteLine("The ambassador with the given code does not exist in the dictionary");
}
Console.ReadLine();
}
public class Ambassador
{
    public CountryCode CountryCode { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}
public class CountryCode
{
    public string Code { get; }
    public CountryCode(string code)
    {
        Code = code;
    }
    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return false;
        }
        if (!(obj is CountryCode))
        {
            return false;
        }
        return StringComparer.OrdinalIgnoreCase.Equals(this.Code, ((CountryCode)obj).Code);
    }
    public override int GetHashCode()
    {
        return StringComparer.OrdinalIgnoreCase.GetHashCode(this.Code);
    }

你的核心疑问

为什么调用ambassadors.TryGetValue时,必须新建一个CountryCode实例作为参数?明明字典里已经存在对应的CountryCode实例,为什么不能直接检查这些已存在的实例?


问题解析

其实这个问题的核心是要理解Dictionary的查找逻辑,以及自定义键类型的工作方式,我分几点给你解释:

  • Dictionary靠「键的相等性」查找,而非实例引用
    Dictionary的本质是哈希表,它判断两个键是否相等,不是看两个实例是不是同一个内存引用,而是通过你重写的Equals和GetHashCode方法来判断。只要两个CountryCode实例的Code(忽略大小写)相同,它们就会被Dictionary视为同一个键——这也是你正确重写这两个方法的意义所在。

  • 你没有现成的匹配实例可以直接传入
    从控制台输入的是字符串code,你手里只有这个字符串,并没有一个对应的CountryCode实例可以直接用。字典里的CountryCode实例是之前创建的,但你输入的时候并不知道用户会输入什么,也没法提前拿到对应的实例(总不能遍历字典先找一遍吧?那Dictionary的O(1)高效查找优势就没了)。

  • TryGetValue的参数类型要求必须是TKey
    你的字典键类型是CountryCode,所以TryGetValue的第一个参数必须是CountryCode类型的对象,不能直接传字符串。所以你必须把输入的字符串转换成CountryCode实例,这里最简单的方式就是新建一个——而由于你已经正确重写了相等性判断方法,这个新建的实例和字典里已有的对应实例会被判定为相等,自然就能找到对应的值。

举个额外的例子:如果提前把所有CountryCode实例存在一个列表里,你也可以先遍历列表找到和输入字符串匹配的实例,再把那个实例传给TryGetValue,但这样做的效率是O(n),远不如直接新建实例做O(1)的哈希查找高效。


内容的提问来源于stack exchange,提问作者Vincent Mazzarella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 08:57:46