为什么我不能将KeyValuePair <TKey,TValue>与默认值进行比较

joh*_*hnc 36 .net c# key-value

在.Net 2.5中,我通常可以在值与其类型默认值之间获得相等比较(==)

if (myString == default(string))
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试在默认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;
}
Run Code Online (Sandbox Code Playgroud)

例外:

运算符'=='不能应用于'System.Collections.Generic.KeyValuePair <string,object>'和'System.Collections.Generic.KeyValuePair <string,object>'类型的操作数

是因为,作为结构,KeyValuePair不可为空吗?如果是这种情况,为什么,实际上,默认是为了处理不可为空的类型?

编辑

为了记录,我选择了@Chris Hannon作为选择的答案,因为他给了我正在寻找的东西,最优雅的选择,以及简洁的解释,但我鼓励阅读@Dasuraga以获得非常全面的解释,为什么这是案子

Chr*_*non 57

发生这种情况是因为KeyValuePair<TKey, TValue>没有定义自定义==运算符,并且未包含在可以使用它的预定义值类型列表中.

以下是该运营商的MSDN文档的链接.

对于预定义的值类型,如果操作数的值相等,则相等运算符(==)返回true,否则返回false.

在这种情况下,您最好选择相等检查,因为这不是您可以控制的结构,default(KeyValuePair<TKey,TValue>).Equals(pair)而是调用.


rtp*_*tpg 5

(如果您不关心与此错误相关的泛型讨论,您可以跳到最后以获得"真实"答案)

正如错误所说,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);
        }
Run Code Online (Sandbox Code Playgroud)

(借口可怕的缩进)

这里我们强制说TKey和TValue都是可比较的(通过CompareTo成员函数).

CompareTo函数(对于预定义类型定义)在两个对象相等时返回0,即la strcmp.a.ComparesTo(b)== 0表示a和b是"相同"(在值中,不是同一个对象).

所以这个函数需要两个KVP(k,v)和(k',v')并且当且仅当k == k'和v == v'时才会返回true(直观意义上).


但这有必要吗?看来你的测试中遇到问题的依据是对FirstOrDefault返回的某种验证.

但是你的函数名为FirstOrDefault是有原因的:

如果未找到此类元素,则返回满足条件的序列的第一个元素或默认.

(强调我的)

如果找不到某些内容,此函数将返回默认值,这意味着如果您的谓词未经过验证,您将获得等于(默认值(TKey),默认值(TValue)的KeyValuePair.

因此,您的代码(打算)检查pair.Key == default(TKey)是否只返回默认值(TKey).从一开始就不会让返回对更合理.