2012-07-12 16 views
4

我有一个List<> N项。当且仅当N = 1时,我想获得第一个元素。可以使用lambda还是其他一些很好的构造来完成此操作?如果只有一个元素,将列表<T>转换为T项?

这工作,但看起来可怕:

var blah = new List<Object>() { new Object() }; 
var item = (blah.Count == 1 ? blah[0] : null); 
+0

如果只用_“only if N = 1”_和_“only if Count = N”来替换_“ – 2012-07-12 08:39:13

+0

”如果只有一个项目**并且它是'null' **,如果有0或2+项目,行为是无法区分的。这个可以吗? – AakashM 2012-07-12 08:40:11

回答

7

有几种LINQ扩展方法。

  1. SingleOrDefault 如果有一个元素会被退回,如果有没有default<T>将被退回,如果有多个抛出一个异常
  2. FirstOrDefault 如果有一个元素会被退回,如果没有,则default<T>将返回
  3. ElementAtOrDefault 返回在给定的位置或元件default<T>如果序列还没有这么多元件

因此,例如,(我的首选为您的要求):

var item = blah.ElementAtOrDefault(0); 

满足您需求的最佳方法取决于如何严格的这条规则是:

我想第一元件当且仅当N = 1时。

如果它是例外在序列中有多个元素,使用SingleOrDefault,如果它失控,您将被通知(错误日志)。

如果它是重要的,你得到第一个元素,你永远不会希望其他元素,用更好的FirstOrDefault,因为它有一个有意义的名字。

如果序列中元素的索引很重要,并且您(当前)需要第一个元素,但将来可能会更改,请使用ElementAtOrDefault

1

我想的SingleOrDefault是你在找什么:

using System.Linq;  
... 
var item = blah.SingleOrDefault(); 
+0

在这种情况下,'Single'可能更合适,如果他们想确保有物品。 – 2012-07-12 08:28:09

+0

如果序列中有多个元素,则会引发异常。 – 2012-07-12 08:29:16

0

它没有看起来好多了,但你可以使用blah.Single()代替blah[0]

var blah = new List<Object>() { new Object() }; 
var item = blah.Count == 1 ? blah.Single() : null; 
0

如果您有:

var blah = new List<MyClass>() { new MyClass() }; 

,你可以这样做:

var item = (blah.Count == 1 ? blah[0].Single<MyClass>() : null); 
4

你可以写你自己的extension method它:

public static class ListExtensions 
{ 
    public static T SingleOrNothing<T>(this IList<T> list) where T : class 
    { 
     if (list.Count == 1) 
      return list.Single(); 
     else 
      return null; 
    } 
} 

然后你只需要调用它在你的代码,例如:

var item = someList.SingleOrNothing(); 
+1

+1。但是你需要添加一个''''类型约束,或者更好的是返回'default(T)'而不是'null'。 – 2012-07-12 08:37:44

+0

@ErenErsönmez:好的电话,我会更新答案。 – David 2012-07-12 08:40:18

相关问题