我有一个IDictionary
我需要选择Bar.Prop1与字符串值匹配的第一个Foo。
public class Foo { }
public class Bar
{
public String Prop1 { get; set; }
}
现在我就这样......
foreach (var kvp in MyDictionary)
{
if (kvp.Value.Prop1 == theString)
{
var key = kvp.Key;
//Do something with it
break;
}
}
但这似乎并不像LINQ Query一样干净。 ReSharper把它变成了:
foreach (var kvp in MyDictionary.Where(kvp => kvp.Value.Prop1 == theString))
{
var key = kvp.Key;
//Do something with it
//break; is unnecessary because I only get one kvp back anyways.
}
我只想要匹配的第一个项目,因为我不希望得到多个KVP。这违背了业务逻辑,因此单元测试会处理这个问题。
答案 0 :(得分:7)
我只想要第一个项目 比赛,因为我没想到 获得多个KVP。那 违背了业务逻辑,所以 单元测试负责这一点。
如果是这种情况,我认为你需要对你的意图使用更强的代码保证,那就是Single
(或SingleOrDefault
)方法。 First
将返回与给定谓词匹配的任意多个的第一个对象。如果很多违背了您的期望和业务规则,那么这似乎是一个错误。这样对待它。
var key = MyDictionary.Single(pair => pair.Value.Prop1 == someValue).Key;
使用Single
,如果序列中有多个匹配项,则会导致异常。
SingleOrDefault
允许0或1,但永远不会更多。如果使用这种方法,您需要捕获结果并在执行其他操作(触发方法,访问属性等)之前与null进行比较。
答案 1 :(得分:5)
var key = MyDictionary.First(kvp => kvp.Value.Prop1 == theString).Key;
答案 2 :(得分:4)
@Bala R的回答是正确的,但Anthony Pegram在他对OP的评论中提出了非常好的观点。如果您使用不同的键执行此操作多次,则应该执行的操作是反转字典,因此每次需要值时都不必遍历整个集合。
// Do this just once: it's expensive
var reverseDict = MyDictionary.ToDictionary(kvp => kvp.Value.Prop1, kvp => kvp.Key);
...
// Do this as many times as you need: it's cheap
var key = reverseDict[someValue];