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

当Font作为键时,.NET Hashtable是否使用专用相等比较器及可用性疑问

.NET WinForms中使用Hashtable管理唯一Font对象的问题解析

问题场景

在.NET Framework WinForms应用中,需要创建一个关联对应对象的唯一Font集合,要求属性(名称、大小等)相同的Font视为同一对象,尝试用Hashtable实现,测试代码如下:

private void Form1_Load(object sender, EventArgs e)
{
    Font font1 = new Font(this.Font, FontStyle.Regular);
    Font font2 = new Font("Microsoft Sans Serif", 8.25f);
    Hashtable ht = new Hashtable();
    ht.Add(font1, 1);
    ht.Add(font2, 2);
}

执行添加font2的语句时抛出异常:

System.ArgumentException HResult=0x80070057 Message=Item has already been added. Key in dictionary: '[Font: Name=Microsoft Sans Serif, Size=8.25, Units=3, GdiCharSet=1, GdiVerticalFont=False]' Key being added: '[Font: Name=Microsoft Sans Serif, Size=8.25, Units=3, GdiCharSet=1, GdiVerticalFont=False]' Source=mscorlib StackTrace: at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) at System.Collections.Hashtable.Add(Object key, Object value) at Font_Hashtable.Form1.Form1_Load(Object sender, EventArgs e)

疑惑点:原本认为Hashtable对对象键是按引用比较,但实际却把属性相同的不同Font实例视为重复键,不确定该场景是否还能使用Hashtable。

异常原因解析

Hashtable的键比较逻辑并非固定为引用比较,而是依赖于键对象自身的Equals()和GetHashCode()实现:

  • Font类重写了Equals()和GetHashCode()方法,会根据字体的名称、大小、样式等属性值来判断相等性,而非引用地址。
  • 测试中的font1和font2属性完全一致,所以Hashtable判定它们是同一个键,抛出重复添加的异常。

场景适用性结论

这个场景完全可以使用Hashtable,甚至它的默认行为正好匹配你的需求:

  • 你需要“属性相同的Font视为同一对象”,而Hashtable利用Font自身的内容相等逻辑,自动帮你过滤了属性重复的Font实例,避免集合中出现属性一致的重复项。
  • 如果后续需要修改比较规则(比如改为引用比较),可以自定义实现IEqualityComparer接口,在创建Hashtable时传入该比较器实例,覆盖默认的相等判断逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:42:47