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

本文关键字:元素 包含多 抛出异常 SingleOrDefault | 更新日期: 2023-09-27 18:14:39

我有字典,很少有元素像

那样存储
    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()

但是我没有很好的解释为什么&当SingleOrDefault()抛出错误?我应该假设字典存储多个值,这就是为什么SingleOrDefault()不会工作?

寻找解释当为什么&当SingleOrDefault()抛出错误....请给我示范一下情况。由于

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

首先,上面的示例数据不会抛出,因为它不包含多个相等的"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

这使你的代码更易读,也遵循了"快速失败"规则。

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

SingleOrDefault当你确定list中只有一个元素时使用,如果它不在list中,它将返回default (null),但如果它有多个值,它将抛出异常。

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