2009-04-09 146 views
19

使用LINQ如果项目可能不存在于列表中,从列表中选择单个项目的最佳方式是什么?从列表中选择单个项目

我想出了两个解决方案,我都不喜欢。我使用where子句来选择项目列表(我知道它只是一个项目),然后我可以检查计数并在此列表中进行单一调用(如果count为1),则另一种选择是使用foreach获得该项目后休息。

这些都不是一个好方法,有没有更好的方法?

回答

32

您可以使用IEnumerable.First()IEnumerable.FirstOrDefault()

不同之处在于,如果找不到元素(或者如果没有元素与条件匹配(如果使用条件),则会抛出First())。 FirstOrDefault()将返回default(T)null如果它是一个引用类型)。

+1

太简单了,不知道我是怎么错过的。谢谢。 – Daniel 2009-04-09 18:04:42

1

也许我在这里丢失了一些东西,但通常调用.SingleOrDefault()是要返回列表中单个元素的方式,或者是列表为空的默认值(引用或可为空的类型为null)。 如果列表包含多个元素,则会生成一个异常。

使用FirstOrDefault()照顾的情况下,你可能有不止一个)

8
List<string> items = new List<string>(); 

items.Find(p => p == "blah"); 

items.Find(p => p.Contains("b")); 

但是这允许您定义您通过比赛谓词找什么...

我想如果你在说linqToSql那么:

例如寻找帐户...

DataContext dc = new DataContext(); 

Account item = dc.Accounts.FirstOrDefault(p => p.id == 5); 

如果您需要确保只有1个项目(抛出异常多的时候1)

DataContext dc = new DataContext(); 

Account item = dc.Accounts.SingleOrDefault(p => p.id == 5); 
2

有两种简单的方法,这取决于如果你想处理异常或获得默认值。

您可以使用First<T>()FirstOrDefault<T>()扩展方法来获得第一个结果或default(T)

var list = new List<int> { 1, 2, 4 }; 
var result = list.Where(i => i == 3).First(); // throws InvalidOperationException 
var result = list.Where(i => i == 3).FirstOrDefault(); // = 0 
14

使用FirstOrDefault选择器。

var list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 

var firstEven = list.FirstOrDefault(n => n % 2 == 0); 

if (firstEven == 0) 
    Console.WriteLine("no even number"); 
else 
    Console.WriteLine("first even number is {0}", firstEven); 

只是传递一个谓词的FirstFirstOrDefault方法,它会高兴地去圆”的名单,并挑选第一场比赛为您服务。

如果没有匹配,FirstOrDefault将返回列表项的任何数据类型的默认值。

希望这有助于:-)

0

SingleOrDefault()是你所需要的

欢呼

4

只是为了完成答案,如果你正在使用LINQ语法,你可以把它包起来,因为它返回一个IEnumerable:

(from int x in intList 
where x > 5 
select x * 2).FirstOrDefault() 
0

刚才看到现在这个样子,如果您正在使用对象的列表,您可以尝试这个

public class user 
{ 
    public string username { get; set; } 
    public string password { get; set; } 
} 

    List<user> userlist = new List<user>(); 

     userlist.Add(new user { username = "macbruno", password = "1234" }); 
     userlist.Add(new user { username = "james", password = "5678" }); 
     string myusername = "james"; 
     string mypassword = "23432"; 

    user theUser = userlist.Find(
      delegate (user thisuser) 
      { 
       return thisuser.username== myusername && thisuser.password == mypassword; 
      } 
      ); 

      if (theUser != null) 
      { 
       Dosomething(); 
      } 
      else 
      { 
       DoSomethingElse(); 

      } 
相关问题