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

如何强制IDictionary的键为特定类层级中的类型?

限制字典键为指定类类型的实现方案

当然可以实现这一需求,下面提供几种实用的方案来确保字典的键只能是BaseClass、SubClass1或SubClass2类型:

方案一:自定义包装类(推荐)

封装内部的字典实例,对外只提供经过校验的操作方法,从根源上控制键的类型:

public class RestrictedTypeDictionary
{
    private readonly IDictionary<Type, int> _innerDictionary = new Dictionary<Type, int>();
    // 定义允许的类型集合
    private readonly HashSet<Type> _allowedTypes = new HashSet<Type>
    {
        typeof(BaseClass),
        typeof(SubClass1),
        typeof(SubClass2)
    };

    public void Add(Type key, int value)
    {
        if (!_allowedTypes.Contains(key))
        {
            throw new ArgumentException($"不允许添加类型「{key.Name}」作为键", nameof(key));
        }
        _innerDictionary.Add(key, value);
    }

    // 按需实现其他字典操作方法,比如取值、删除等
    public bool TryGetValue(Type key, out int value)
    {
        return _innerDictionary.TryGetValue(key, out value);
    }
}

这种方式操作简单且安全,外部无法直接访问内部字典,彻底避免违规添加。

方案二:实现IDictionary接口

如果需要让类兼容IDictionary<Type, int>接口以适配现有代码,可以实现该接口并在关键操作中加入类型校验:

public class RestrictedTypeDict : IDictionary<Type, int>
{
    private readonly Dictionary<Type, int> _innerDict = new Dictionary<Type, int>();
    private readonly HashSet<Type> _allowedTypes = new HashSet<Type>
    {
        typeof(BaseClass),
        typeof(SubClass1),
        typeof(SubClass2)
    };

    public void Add(Type key, int value)
    {
        ValidateKey(key);
        _innerDict.Add(key, value);
    }

    public int this[Type key]
    {
        get => _innerDict[key];
        set
        {
            ValidateKey(key);
            _innerDict[key] = value;
        }
    }

    private void ValidateKey(Type key)
    {
        if (!_allowedTypes.Contains(key))
        {
            throw new ArgumentException($"类型「{key.Name}」不在允许的键类型范围内", nameof(key));
        }
    }

    // 实现IDictionary的其他接口方法,按需委托给内部字典
    public bool ContainsKey(Type key) => _innerDict.ContainsKey(key);
    public bool Remove(Type key) => _innerDict.Remove(key);
    public bool TryGetValue(Type key, out int value) => _innerDict.TryGetValue(key, out value);
    public ICollection<Type> Keys => _innerDict.Keys;
    public ICollection<int> Values => _innerDict.Values;
    public void Add(KeyValuePair<Type, int> item)
    {
        ValidateKey(item.Key);
        _innerDict.Add(item.Key, item.Value);
    }

    // 其余接口方法(如Clear、Contains、CopyTo等)按需实现即可
}

这种方式保持了字典接口的兼容性,但需要实现所有接口方法,代码量稍大。

方案三:结合泛型约束与运行时校验

提供泛型方法实现编译期的初步约束,同时加入运行时检查,兼顾类型安全和灵活性:

public class TypedRestrictedDict
{
    private readonly IDictionary<Type, int> _innerDict = new Dictionary<Type, int>();

    public void Add<T>(int value) where T : BaseClass
    {
        var type = typeof(T);
        // 严格限制只能是指定的三种类型
        if (type != typeof(BaseClass) && type != typeof(SubClass1) && type != typeof(SubClass2))
        {
            throw new ArgumentException($"不允许添加类型「{type.Name}」作为键", nameof(T));
        }
        _innerDict.Add(type, value);
    }

    // 按需实现其他操作方法
}

使用时通过dict.Add<BaseClass>(1);的方式调用,编译期会阻止非BaseClass派生类传入,但如果存在其他BaseClass的子类(如SubClass3),仍需运行时校验来拦截。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:05:19