在LINQ中混合Any()和First()?

Gui*_*shy 8 c# linq

首先是LINQ中的菜鸟!那么,问题是我有一个集合:

  1. 要么不包含我的ID(字符串)
  2. 或仅包含一次

我想使用Where但我不喜欢if我必须做的说明......所以这是我的代码:

if (MyCollection.Any(rm => rm.BaseName == rbName))
{
    var tmp = MyCollection.First(rm => rm.BaseName == rbName);
}
Run Code Online (Sandbox Code Playgroud)

这有效,但我真的觉得这不是我应该用LINQ做的方式......有什么建议吗?

Llo*_*ell 16

非唯一实体答案(除了抛出多个实例)

使用SingleOrDefault.这将返回唯一项(如果存在),如果不存在,则返回null;如果存在多个项,则返回异常.

var tmp = MyCollection.SingleOrDefault(rm => rm.BaseName == rbName);
Run Code Online (Sandbox Code Playgroud)

唯一属性答案(永远不会有多个实例)

如果您的系统设置BaseName为一个唯一的实体,用户FirstOrDefault,如果有多个因为它将在第一个实例停止,则不会抛出异常,但是系统将被设计为永远不会有相同的实例,所以这是可以接受的(并且减少时间).

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName);
Run Code Online (Sandbox Code Playgroud)

  • 在某种程度上,如果有匹配,它就会抛出异常,但如果您的系统设置为不可能出现重复,则永远不需要该异常,然后使用 FirstOrDefault (仅当它是主项时)键或已在插入时设置验证)。 (2认同)

Jon*_*eet 12

正如ThePower所说,你应该使用SingleOrDefault或者也许FirstOrDefault.如果真的只有一个这样的条目,他们会做同样的事情,但FirstOrDefault如果你使用LINQ to Objects可能会更快 - SingleOrDefault必须扫描整个序列以检查没有任何其他匹配.

如果有多个匹配项,SingleOrDefault则会抛出异常; FirstOrDefault只会返回第一场比赛.

所以你可以使用:

var result = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName);
if (result != null)
{
    // Use it
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您的序列元素类型是值类型,这可能会很麻烦,因为您可能无法区分由于没有匹配而导致的元素类型的默认值,以及"实际"值.看起来在这种情况下不太可能出现问题,但值得记住.


Har*_*san 5

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName));
Run Code Online (Sandbox Code Playgroud)

如果你没有这样的记录,tmp将为null.