泛型KeyValue(手动字典)键比较不兼容的类型约束问题咨询
解决泛型Dictionary中Key比较的问题
首先得说,你当前的代码有个小设计问题:你的KeyValueGeneric<T>把Key和Value都用了同一个泛型参数T,这意味着Key和Value必须是同一种类型,而真正的Dictionary是支持Key和Value不同类型的。所以第一步我们先把这个结构改成支持两个独立的泛型参数,这样更符合Dictionary的实际用途。
接下来就是你遇到的核心问题:泛型类型T默认没有定义==运算符的比较规则,编译器不知道怎么去比较两个T类型的实例。解决这个问题有两种常用的方案,我会分别说明,然后给出修改后的完整代码。
方案1:给Key类型添加IEquatable<TKey>约束(推荐)
这种方式类型安全,还能避免值类型的装箱操作,是比较规范的做法。我们需要:
- 把
KeyValueGeneric改成KeyValueGeneric<TKey, TValue>,分别指定Key和Value的类型 - 给
MyDictionaryGenerics<TKey, TValue>添加where TKey : IEquatable<TKey>约束,确保Key类型实现了相等比较的接口 - 把比较逻辑从
==改成调用Equals方法
方案2:使用object.Equals进行比较(无约束)
如果你不想给Key类型加约束,可以直接用object.Equals方法,它能兼容所有类型(包括值类型和引用类型),但对于值类型会有轻微的装箱开销。
修改后的完整代码(方案1,推荐版)
class Generic_Key_Value { // 改成两个泛型参数,分别对应Key和Value的类型 public struct KeyValueGeneric<TKey, TValue> { public readonly TKey Key; public readonly TValue Value; public KeyValueGeneric(TKey key, TValue value) { Key = key; Value = value; } } // 同样使用两个泛型参数,并且给TKey添加IEquatable<TKey>约束 public class MyDictionaryGenerics<TKey, TValue> where TKey : IEquatable<TKey> { public KeyValueGeneric<TKey, TValue>[] keyArray = new KeyValueGeneric<TKey, TValue>[20]; public int Counter = 0; public TValue this[TKey key] { set { bool matchFound = false; for (int i = 0; i < Counter; i++) { // 使用Equals方法进行比较,符合IEquatable<TKey>的约束 if (key.Equals(keyArray[i].Key)) { keyArray[i] = new KeyValueGeneric<TKey, TValue>(key, value); matchFound = true; break; // 找到匹配后可以直接跳出循环,提升效率 } } if (!matchFound) { keyArray[Counter] = new KeyValueGeneric<TKey, TValue>(key, value); Counter++; } } get { for (int i = 0; i < Counter; i++) // 这里改成Counter而不是keyArray.Length,避免遍历空元素 { if (key.Equals(keyArray[i].Key)) { return keyArray[i].Value; } } throw new System.Collections.Generic.KeyNotFoundException(); } } } }
额外优化点说明
- 我把getter里的循环上限从
keyArray.Length改成了Counter,因为keyArray的长度是20,但实际存储的元素只有Counter个,这样能避免遍历空元素,提升效率 - 在setter的循环里找到了匹配项后添加了
break,不用继续遍历后面的元素
如果你想用方案2(无约束)
只需要把MyDictionaryGenerics的约束去掉,然后把比较代码改成:
if (object.Equals(key, keyArray[i].Key))
这样即使Key类型没有实现IEquatable<TKey>,也能正常进行相等比较。
内容的提问来源于stack exchange,提问作者slipperyHippo
相关产品推荐
相关产品推荐

