CSharp - LINQ何时使用.first以及何时使用.FirstOrDefault?

  显示原文与译文双语对照的内容

我已经搜索过了,没有找到一个明确的答案,关于什么时候你想使用 .First,什么时候你想使用 .FirstOrDefault

  • 你希望什么时候使用 .First? 只有在没有返回结果的情况下才能捕获异常?

    
    var result = List.Where(x => x =="foo").First();
    
    
  • 你希望什么时候使用 .FirstOrDefault? 如果没有结果,则总是需要默认类型?

    
    var result = List.Where(x => x =="foo").FirstOrDefault();
    
    
  • 那么,考虑到?

    
    var result = List.Where(x => x =="foo").Take(1);
    
    
时间:

当我知道或者期望序列至少有一个元素时,我将使用 First() 。 换句话说,当序列为空时发生异常。

当你知道是否需要检查是否有元素时使用 FirstOrDefault() 。 换句话说,当序列为空时,。 你不应该依赖于检查的异常处理。 ( 这是不好的做法,可能会影响性能) 。

最后,First()Take() 之间的区别是 First() 返回元素本身,而 Take() 返回一个元素序列,其中包含一个元素。 ( 如果你将 1作为参数传递) 。

如果没有要返回的行,. First() 将抛出异常,而. FirstOfDefault() 将返回默认值( 所有引用类型的NULL ) 。

所以如果你准备好并愿意处理一个可能的异常,.First() 是很好的。 如果你想要检查!= null的返回值,那么 .FirstOrDefault() 是你更好的选择。

但我想这有点个人喜好。 使用任何对你更有意义的方式,更好地适应你的编码风格。

首先,Take 是一个完全不同的方法。 它返回一个 IEnumerable<T>,而不是一个 T,所以这就不存在了。

FirstFirstOrDefault 之间,当你确信某个元素存在并且它不存在时,应该使用 First,然后有一个错误。

顺便说一下,如果你的序列包含 default(T) 元素( 例如。 null ),你需要区分为空和第一个是 null的元素,你不能使用 FirstOrDefault

另一个不同之处是,如果在生产环境中调试应用程序,你可能无法访问行号,因此识别方法中的特定 .First() 语句会导致异常可能很困难。

异常消息也不会包含任何你可能使用过的Lambda表达式,这将导致任何问题,甚至难以调试。

这就是为什么我总是使用 FirstOrDefault(),即使我知道一个空的条目会构成异常的情况。


var customer = context.Customers.FirstOrDefault(i => i.Id == customerId);
if (customer == null)
{
 throw new Exception(string.Format("Can't find customer {0}.", customerId));
}


someList.First();//exception if collection is empty.
someList.FirstOrDefault();//first item or default(Type)

使用哪一个它应该由业务逻辑决定,而不是对异常/程序失败的恐惧。

例如如果业务逻辑说我们不能在任何工作日都有零事务,( 假设) 。 那么你就不应该用一些智能编程来处理这个场景。 我将始终使用 First() 一下这样的集合,如果其他地方做了错误的业务逻辑,并让程序失败。

代码:


var transactionsOnWorkingDay = GetTransactionOnLatestWorkingDay();
var justNeedOneToProcess = transactionsOnWorkingDay.First()://Not FirstOrDefault()

我想看到其他人对此的评论。

好的,让我给我两个分数。 第一个/firstordefault用于使用第二个构造函数。 我不会解释它是什么,但是当你可能总是使用它是因为你不想引起一个异常。


person = tmp.FirstOrDefault(new Func<Person, bool>((p) =>
{
 return string.IsNullOrEmpty(p.Relationship);
}));

...