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

自定义泛型字典实现校验及GeoLocation作为键的适配咨询

C#泛型字典与自定义键类型解决方案

一、自定义Dict<K,V>适配IDictionary<K,V>的检查要点

要完全实现IDictionary<K,V>,你需要覆盖它继承的所有接口成员,核心检查项如下:

  • 核心字典成员:
    • void Add(K key, V value):必须检查键是否已存在,重复则抛ArgumentException
    • bool ContainsKey(K key):准确判断指定键是否在字典中
    • bool Remove(K key):移除对应键值对,返回操作是否成功
    • bool TryGetValue(K key, out V value):键存在时返回值,不存在时返回默认值且方法返回false
    • V this[K key] { get; set; }:get操作键不存在需抛KeyNotFoundException,set操作直接覆盖已有键的值
  • ICollection<KeyValuePair<K,V>>要求的成员:
    • void Add(KeyValuePair<K,V> item):和Add(K,V)逻辑一致,不能添加重复键
    • void Clear():清空所有键值对
    • bool Contains(KeyValuePair<K,V> item):需同时匹配键和值
    • void CopyTo(KeyValuePair<K,V>[] array, int arrayIndex):按要求将键值对复制到目标数组
    • bool Remove(KeyValuePair<K,V> item):匹配键值对后移除
    • int Count { get; }:实时返回当前键值对数量
    • bool IsReadOnly { get; }:固定返回false(自定义字典默认是可修改的)
  • 枚举器实现:
    显式实现IEnumerable<KeyValuePair<K,V>>的GetEnumerator(),非泛型IEnumerable的GetEnumerator()可以直接调用泛型版本避免重复代码

你可以对照官方IDictionary<K,V>的成员列表逐一核对,重点关注键唯一性的校验逻辑,这是字典的核心规则。

二、让GeoLocation结构体作为自定义Dict的键

和System.Collections.Generic.Dictionary的规则完全一致,自定义键类型必须满足相等性判断和哈希值计算的要求,具体实现步骤:

  1. 实现IEquatable<GeoLocation>接口(避免装箱,提升性能)
  2. 重写object.Equals()和GetHashCode()方法
  3. 可选重载==和!=运算符,让相等判断更直观

示例代码如下:

public struct GeoLocation : IEquatable<GeoLocation>
{
    public double Latitude { get; }
    public double Longitude { get; }

    public GeoLocation(double latitude, double longitude)
    {
        Latitude = latitude;
        Longitude = longitude;
    }

    // 精准判断两个坐标是否相等(注意浮点数的精度误差)
    public bool Equals(GeoLocation other)
    {
        const double precision = 1e-9;
        return Math.Abs(Latitude - other.Latitude) < precision 
            && Math.Abs(Longitude - other.Longitude) < precision;
    }

    public override bool Equals(object obj)
    {
        return obj is GeoLocation location && Equals(location);
    }

    // 基于坐标生成唯一哈希值,避免字典键冲突
    public override int GetHashCode()
    {
        return HashCode.Combine(Latitude, Longitude);
    }

    // 重载运算符让相等判断更符合直觉
    public static bool operator ==(GeoLocation left, GeoLocation right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(GeoLocation left, GeoLocation right)
    {
        return !(left == right);
    }
}

完成后,你的自定义Dict<GeoLocation, City>就可以像系统字典一样使用:添加相同坐标的键会触发重复检查,通过坐标键能精准获取对应值,完全遵循系统字典的使用逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:45:37