Dictionary.FirstOrDefault() 如何确定是否找到结果
我有(或想要有)一些像这样的代码:
IDictionary<string,int> dict = new Dictionary<string,int>();
// ... Add some stuff to the dictionary.
// Try to find an entry by value (if multiple, don't care which one).
var entry = dict.FirstOrDefault(e => e.Value == 1);
if ( entry != null ) {
// ^^^ above gives a compile error:
// Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and '<null>'
}
我也尝试像这样更改有问题的行:
if ( entry != default(KeyValuePair<string,int>) )
但这也给出了编译错误:
Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and 'System.Collections.Generic.KeyValuePair<string,int>'
这里给出了什么?
I have (or wanted to have) some code like this:
IDictionary<string,int> dict = new Dictionary<string,int>();
// ... Add some stuff to the dictionary.
// Try to find an entry by value (if multiple, don't care which one).
var entry = dict.FirstOrDefault(e => e.Value == 1);
if ( entry != null ) {
// ^^^ above gives a compile error:
// Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and '<null>'
}
I also tried changing the offending line like this:
if ( entry != default(KeyValuePair<string,int>) )
But that also gives a compile error:
Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair<string,int>' and 'System.Collections.Generic.KeyValuePair<string,int>'
What gives here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
对于可空值类型,只需检查即可。
对于不可为 null 的类型,检查默认值;对于 int,检查默认值 0。
for nullable value types, just check.
for non-nullable types check againts default value, for int, 0.
公平地说,强制转换对象或使用 select 语句是不必要的,我也不会依赖 try catch 来解决问题。
既然您无论如何都在使用 Linq,那么使用 .Any 有什么问题吗?
显然,请使用它来适应您的解决方案,但这是一个相当快速的检查,如果它在集合中找到具有该值的项目,则会停止。因此,如果找到匹配项,它不会检查所有值。
MSDN 文档:
https://msdn.microsoft.com/en -us/library/bb534972(v=vs.110).aspx
To be fair, casting the object or using a select statement is unnecessary, I wouldn't rely on a try catch to fix the issue either.
Since you're using Linq anyway, what's wrong with using .Any?
Obviously, play with it to fit your solution, but it's a fairly quick check that stops if it finds an item in the collection with that value. So it won't check all values if a match has been found.
MSDN Documentation:
https://msdn.microsoft.com/en-us/library/bb534972(v=vs.110).aspx
应用于 Dictionary 的 Linq FirstOrDefault 无论如何都会返回不可为 null 的 keyValuePair 对象。
正确的方法是检查结果键或值是否不等于默认类型值
Linq FirstOrDefault applying to a Dictionary returns not nullable keyValuePair object anyway.
The right way is to check result key or value that it doesn't equal default type value
这样做:
问题是
FirstOrDefault
方法返回一个KeyValuePair
是一个值类型,因此它永远不可能是null
。您必须通过检查其Key
、Value
属性中至少一个是否具有默认值来确定是否找到某个值。Key
的类型为string
,因此考虑到字典中不能包含带有null< 的项目,因此检查
null
是有意义的/代码> 键。您可以使用的其他方法:
这会将结果投影到可空整数的集合中,如果该集合为空(没有结果),您将得到一个空值 - 您不可能将其误认为是
int
成功的搜索将会产生结果。Do it this way:
The thing is that the
FirstOrDefault
method returns aKeyValuePair<string, int>
which is a value type, so it cannot ever benull
. You have to determine if a value was found by checking if at least one of itsKey
,Value
properties has its default value.Key
is of typestring
, so checking that fornull
makes sense considering that the dictionary could not have an item with anull
key.Other approaches you could use:
This projects the results into a collection of nullable ints, and if that is empty (no results) you get a null -- there's no way you can mistake that for the
int
that a successful search would yield.无论 Key 和 Value 的类型如何,您都可以执行以下操作:
Regardless of the types of Key and Value, you could do something like this:
我认为最清晰的代码是这样的:
虽然从速度的角度来看这不太好,但也没有更好的解决方案。这意味着第二次会以慢速搜索字典。 Dictionary 类应该通过提供方法“bool TryGetKey(value)”来改进。它看起来有点奇怪 - 因为字典被认为是在另一个方向使用 - 但有时向后翻译是不可避免的。
The clearest code I think is this:
Though from the standpoint of speed it's not nice, but there is no better solution. This means that the dictionary will be searched with a slow search a second time. The Dictionary class should be improved by offering a method 'bool TryGetKey(value)'. It looks a little bit strange - because a dictionary is thought to be used in the other direction - but sometimes it's unavoidable to translate backwards.
乔恩的答案将适用于
Dictionary
,因为字典中不能有空键值。但是,它不适用于Dictionary
,因为它不代表空键值...“失败”模式最终会出现键为 0。两个选项:
编写一个
TryFirstOrDefault
方法,如下所示:或者,投影为可空类型:
Jon's answer will work with
Dictionary<string, int>
, as that can't have a null key value in the dictionary. It wouldn't work withDictionary<int, string>
, however, as that doesn't represent a null key value... the "failure" mode would end up with a key of 0.Two options:
Write a
TryFirstOrDefault
method, like this:Alternatively, project to a nullable type: