SingleOrDefault()抛出异常Sequence包含多个匹配元素

时间:2014-07-24 11:50:10

标签: c# linq dictionary

我有字典,并且存储的元素很少,如

    Dictionary<string, string> dService = new Dictionary<string, string>();
    dService.Add("UPS Express Plus", "001");
    dService.Add("UPS Express Plus", "054");
    dService.Add("UPS Express", "007");
    dService.Add("UPS Express Saver", "065");
    dService.Add("UPS Expedited", "008");
    dService.Add("UPS Express Plus", "001");

这样我就试图根据价值获得关键

dService.SingleOrDefault(x => x.Value == ("001")).Key

此代码抛出错误。我搜索谷歌并获得解决方案,人们说不要使用SingleOrDefault()而是使用FirstOrDefault()

但我没有得到很好的解释为什么&amp;当SingleOrDefault()抛出错误?我应该假设字典存储了多个值,这就是SingleOrDefault()不起作用的原因吗?

寻找解释为什么&amp;当SingleOrDefault()抛出错误时......请指导我样例情况。感谢

3 个答案:

答案 0 :(得分:4)

首先,上面的示例数据不会抛出,因为它不包含多个"001"的相等值。如果您使用Value="001"添加两个值,那就可以了。

如果您枚举字典,则会获得IEnumerable<KeyValuePair<TKey, TValue>>。您要求字典"001"中的第一个且唯一值。当然,字典可以包含多个相等的(但只包含唯一键)。

因此,您可以使用FirstOrDefault代替不会产生多个结果的内容。另一种方法是使用Where查找所有内容,然后使用Select密钥:

IEnumerable<string> all001ValKeys = dService
    .Where(kv => kv.Value == "001")
    .Select(kv => kv.Key);
如果您想确保以下业务规则,

SingleOrdefault(或Single)非常方便:

var record = someTable.Single(obj => obj.ID == 123); // ID must be unique

这使您的代码更具可读性,并且遵循&#34;快速失败&#34; -rule。

答案 1 :(得分:2)

如果你想要列表中的第一个元素,则使用FirstOrDefault,如果列表中没有数据,它将返回默认值(为空),否则它将返回列表的第一个元素。

当您确定列表中只有一个元素时使用SingleOrDefault,如果它不在列表中,它将返回默认值(为空),但如果它具有多个单值,则会引发您的异常。

我希望这个解释对你有用。

答案 2 :(得分:0)

请注意,Dictionary上的FirstOrDefault会返回一个KeyValuePair,其中包含已定义的Key和Value类型的默认值。由于您使用字符串作为键和值,因此两者都将为空。因此,LINQ表达式的结果将为null,并且使用该键可能会在代码中导致NullReferenceException。