我喜欢在C#中使用的一种常见模式是,我不需要先用Any
检查集合中是否存在某个东西,然后再用First
查找它,而是简单地调用FirstOrDefault
,它告诉我它是否存在,如果存在,则给我一个对它的引用:
List<Person> people = ...;
Person found;
if ((found = people.FirstOrDefault(x => x.Age > 10)) != null) {
// Found person with age over 10, and we have them in 'found'
//...
}
当被找到的对象是一个引用类型时,这是有效的,并且可以为空。然而,我试图对Dictionary
的条目做同样的事情:
Dictionary<(int X, int Y), ITileData<(int X, int Y)>> srchField = new();
KeyValuePair<(int X, int Y), ITileData<(int X, int Y)>> next;
while ((next = srchField.FirstOrDefault(x => !x.Value.Reached)) != null) {
// Found next, and we have it in 'next'
//...
}
但是,这并不起作用,因为srchField.FirstOrDefault(...)
返回一个KeyValuePair<TKey, TValue>
,它是一个结构体。我可以通过首先在srchField
上调用Any
来解决这个问题,如果Any
找到了任何东西,则使用相同的 predicate 调用First
,但这必须进行两次相同的搜索。有没有什么方法可以进行2合1的存在性检查并存储在这里,在LINQ?中只执行一次词典搜索
2条答案
按热度按时间nxagd54h1#
感谢@TheodorZoulias为我指出了正确的方向,并受到@Samuel的答案和@JonSkeet的代码解决方案的启发(我实际上没有意识到,如果LINQ
.Take(1)
只找到0个元素,它实际上会给您一个0的枚举值,而不是引发异常),我想出了一个很好地完成此任务的扩展方法:示例用法:
nqwrtyyt2#
如果你想在搜索中忽略键,并且你的值是引用类型,你可以只使用字典的
Values
属性:如果你想用钥匙做点什么,那就有点笨拙了: