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

本文关键字:First Any LINQ 混合 | 更新日期: 2023-09-27 18:20:04

首先我是LINQ中的一个noob!然后,问题是我有一个集合:

  1. 其中一个不包含我的ID(字符串)
  2. 或只包含一次

我想使用Where,但我不喜欢必须执行的if指令……所以这是我的代码:

if (MyCollection.Any(rm => rm.BaseName == rbName))
{
    var tmp = MyCollection.First(rm => rm.BaseName == rbName);
}

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

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

非唯一实体应答(在多个实例上引发异常)

使用SingleOrDefault。如果存在,它将返回唯一项;如果不存在,则返回null;如果存在多个项,则返回抛出和异常。

var tmp = MyCollection.SingleOrDefault(rm => rm.BaseName == rbName);

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

如果你的系统设置为BaseName是一个唯一的实体,用户FirstOrDefault,如果有多个,这不会引发异常,因为它会在第一个实例停止,但系统的设计将永远不会有相同的实例,因此这是可以接受的(并减少时间)。

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName);

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

如果有多个匹配,SingleOrDefault将抛出异常;FirstOrDefault将只返回第一场比赛。

所以你可以使用:

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

请注意,如果您的序列元素类型是值类型,这可能会很尴尬,因为由于没有匹配项,您可能无法区分元素类型的默认值和"真实"值。在这种情况下,这看起来不太可能成为问题,但值得记住。

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName));

如果您没有这样的记录,这里的tmp将为null。

您可以使用

FirstOrDefault()

SingleOrDefault()

使用FirstOrDefault(rm => rm.BaseName == rbName);

msdn链接

Any返回bool以指示如果存在此类项目,First将返回集合中的记录。所以在任何情况下,您都会有来自集合的对象和您的条件结果。您可以使用FirstOrDefault,然后检查返回值的null

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName);
if (tmp != null) 
{
    // do something
}
var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName);
if (tmp != null)
{
    // Do something
}