【发布时间】:2022-01-02 19:08:14
【问题描述】:
当涉及到盒装类型时,我对字典如何比较键有点困惑。
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
int i = 5;
int n = 5;
object boxedI = i;
object boxedN = n;
Console.WriteLine("i == n ? " + (i == n) ); //true
Console.WriteLine("bI == bN ? " + (boxedI == boxedN) ); //false
Dictionary<object,int> _dict = new Dictionary<object,int> ();
_dict.Add(boxedI,5);
Console.WriteLine("_dict contains boxedI? " + _dict.ContainsKey(boxedI) ); //true
Console.WriteLine("_dict contains boxedN? " + _dict.ContainsKey(boxedN) ); //!! also true, surprise me
_dict.Add(boxedN,5);//exception
}
}
我预计,由于相等运算符“失败”(AFAIK 它基于方法 GetHashCode,与字典用于构建其内部哈希表表单对象的方法相同),那么字典也应该“失败”盒装 I 和 N 的比较,但那是不是这样的。
这是我使用的小提琴:https://dotnetfiddle.net/DW54nN
所以我问是否有人可以向我解释这里附加了什么以及我在我的心智模型中缺少什么。
【问题讨论】:
-
这是一个引用与值类型的东西,当你使用对象时它会变成一个值,所以当你比较它们时,它们会比较引用(boxedI和boxedN的两个引用不一样)当您使用
_dict.ContainsKey(boxedN)时,它使用引用类型中的值 -
嗯,更重要的是它使用 Equals 和 GetHashCode。如果您调用
boxedI.Equals(boxedN)将返回 true,并且如果您对它们都调用 GetHashCode,它们将返回相同的值。 -
@JonSkeet 所以我的错误是假设 == 操作数等价于 Equals 等价(只需阅读关于 C# corer 的帖子)。感谢简洁明了。
标签: c# dictionary equality boxing