为什么我无法将KeyValuePair <TKey,TValue>与默认值进行比较
在.Net 2.5中,我通常可以获得值与其类型默认值之间的等式比较(==)
if (myString == default(string))
但是,当我尝试在默认的KeyValuePair和KeyValuePair上运行相等比较时,我得到以下异常
代码示例(来自预扩展方法,proto-lambda静态ListUtilities类:))
public static TKey
FirstKeyOrDefault<TKey, TValue>(Dictionary<TKey, TValue> lookups,
Predicate<KeyValuePair<TKey, TValue>> predicate)
{
KeyValuePair<TKey, TValue> pair = FirstOrDefault(lookups, predicate);
return pair == default(KeyValuePair<TKey, TValue>) ?
default(TKey) : pair.Key;
}
例外:
运算符'=='不能应用于'System.Collections.Generic.KeyValuePair <string,object>'和'System.Collections.Generic.KeyValuePair <string,object>'类型的操作数
这是否是因为,作为一个结构,KeyValuePair不能为空? 如果是这种情况,那么为什么(可能是默认)被实现来处理不可为空的类型呢?
编辑
为了记录,我选择了@Chris Hannon作为选定的答案,因为他给了我我正在寻找的东西,最优雅的选择以及简洁的解释,但是我鼓励读@Dasuraga来解释为什么这是一个非常全面的解释案子
发生这种情况是因为KeyValuePair<TKey, TValue>
未定义自定义==运算符,并且未包含在可使用它的预定义值类型列表中。
这里是该运营商的MSDN文档的链接。
对于预定义的值类型,如果操作数的值相等,则相等运算符(==)返回true,否则返回false。
在这种情况下,最好的选择是平等检查,因为这不是一个你可以控制的结构,而是调用default(KeyValuePair<TKey,TValue>).Equals(pair)
来代替。
(如果你不关心与这个错误有关的泛型讨论,你可以跳到最后以获得“真实”答案)
正如错误所述,KeyValuePairs没有相等性测试(即没有内置比较方法)。 原因是为了避免对KeyValuePairs的类型设置约束(有很多情况下,不会进行关键的值比较)。
显然,如果你想比较KeyValuePairs,我想你会想要检查键和值是否相等。 但这意味着一大堆事情,特别是TKey和TValue都是可比类型(即它们实现了IComparable接口)
您可以在keyvaluepairs之间编写自己的比较函数,例如:
static bool KeyValueEqual<TKey , TValue>(KeyValuePair<TKey, TValue> fst,
KeyValuePair<TKey, TValue> snd)
where TValue:IComparable
where TKey:IComparable
{
return (fst.Value.CompareTo(snd.Value)==0)
&& (snd.Key.CompareTo(fst.Key)==0);
}
(请原谅可怕的缩进)
这里我们强加TKey和TValue是可比的(通过CompareTo成员函数)。
当两个对象相等时,CompareTo函数(如为预定义类型定义的)返回0。 a.ComparesTo(b)== 0表示a和b是“相同的”(在值中,而不是相同的对象)。
所以这个函数需要两个KVP(k,v)和(k',v')并且当且仅当k == k'和v == v'(在直观意义上)才会返回true。
但这是必要的吗? 看起来你的测试问题是基于对FirstOrDefault返回的某种验证。
但是有一个原因叫做FirstOrDefault:
如果未找到此元素,则返回满足条件或默认值的序列的第一个元素。
(强调我的)
如果没有找到某个东西,这个函数返回默认值 ,这意味着如果你的谓词没有被验证,你会得到一个KeyValuePair等于(默认(TKey),默认值(TValue)。
因此你的代码(打算)检查pair.Key == default(TKey), 反正只返回默认的(TKey) 。 从一开始就返回pair.Key不是更有意义吗?
为了在任何类或结构上使用“==”等号运算符,它需要覆盖该运算符:http://msdn.microsoft.com/en-us/library/ms173147(v=vs.80)。 ASPX
KeyValuePair不,因此你会得到编译错误。 请注意,如果你只是试试这个,你会得到同样的错误:
var k1 = new KeyValuePair<int,string>();
var k2 = new KeyValuePair<int,string>();
bool b = k1 == k2; //compile error
编辑:正如Eric Lippert在评论中纠正了我,类显然不需要覆盖“==”的相等运算符是有效的。 它会很好地编译并进行参考平等检查。 我的错。
链接地址: http://www.djcxy.com/p/58613.html上一篇: Why can't I compare a KeyValuePair<TKey, TValue> with default