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以获得非常全面的解释,为什么这是案子
(如果您不关心与此错误相关的泛型讨论,您可以跳到最后以获得"真实"答案)
正如错误所说,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).从一开始就不会让返回对更合理.