2011-03-23 56 views
0

閱讀微軟here關於產品的LINQ

 var query = from Student student in arrList 
        where student.Scores[0] > 95 
        select student; 

     foreach (Student s in query) 
      Console.WriteLine(s.LastName + ": " + s.Scores[0]); 

的例子後,我有一個問題:

是否有可能避免的循環?

foreach (Student s in query) 
     Console.WriteLine(s.LastName + ": " + s.Scores[0]); 

如果我重寫查詢並假定我的查詢將總是返回一個結果,該怎麼辦。

var query = from Student student in arrList 
       where student.FirstName == "Cesar" 
       select student; 

我不需要做一個循環...我知道我的查詢只返回一個元素。

+0

不要猶豫編輯我的頭銜。我不知道如何恢復這個問題。 – 2011-03-23 22:33:31

回答

4

它仍然是IEnumerable,但有一個項目。如果要提取它,你可以使用First()甚至更​​好Single()

var query = from Student student in arrList 
      where student.FirstName == "Cesar" 
      select student; 

var student = query.Single(); 

您也可以通過使用Single/First重載方法更換整個where條款:

var emperor = arrList.Single(s => s.FirstName == "Cesar"); 

SingleFirst因爲更嚴格它也會檢查是否有返回的項目。

+1

也許值得注意......如果'arrList'是一個已知含有唯一值的內存中集合,'First'會給你更好的性能。在找到第一場比賽後,'Single'將檢查另一場比賽,最糟糕的情況是,這場比賽可能會穿過整個場館。 – 2011-03-23 22:49:08

0
var query = from Student student in arrList 
     where student.FirstName == "Cesar" 
     select student; 

使用這種query.First()。姓氏

if (query.Count() > 0) 
    Console.WriteLine(query.First().LastName + ": " + query.First().Scores[0]); 
3

FirstOrDefault,我喜歡的方式鏈語法,比如,

arrList.FirstOrDefault(s => s.FirstName == "Cesar"); 
0

可以使用FirstOrDefault()方法。

這是你的查詢,重新寫...

var student = (from Student student in arrList 
       where student.FirstName == "Cesar" 
       select student).FirstOrDefault(); 

您的查詢也可以寫成,鏈接方法。在我看來,這是對眼睛更容易...

arrList.Where(student => student.FirstName == "Cesar").FirstOrDefault(); 

甚至更​​多凝結......

arrList.FirstOrDefault(student => student.FirstName == "Cesar"); 
0

您可以絕對避免調用循環,如果你知道有隻打算返回1個記錄/對象。

看看.First(),.FirstOrDefault(),.Single(),SingleOrDefault()擴展方法。

0

在拉姆達方式

arrList.SingleOrDefault(q => q.Scores[0] > 95); 
0

對於你的問題的第2部分,你可以明確地返回一個Student對象:

var student = (from Student s in arrList where s.FirstName == "Cesar" select student).FirstOrDefault(); 
0

查詢會在這種情況下的IEnumerable<Student>

IEnumerable<T>本身不具有的擴展方法,使您可以執行每一個動作枚舉T,例如像List<T>確實有ForEach<T>(Action<T>)。你當然可以寫擴展方法來做到這一點,我相信很多人都有,但這是一個沒有它的設計決定(an article by Eric Lippert that discusses this)。

如果你知道你的表達式總是會返回一個結果,那麼你可以在預計集合上調用.First()(假設你知道總會有至少一個結果)。

var query = (from Student student in arrList 
      where student.Scores[0] > 95 
      select student).First(); 

Console.WriteLine(query.LastName + ": " + query.Scores[0]); 
0

假設只有一個結果將被返回可能是危險的。 95分以上的學生多於一名?

您可以使用lambda表達式,壓縮您的代碼:

arrList.ForEach(s => Console.WriteLine(s.LastName + ": " + s.Scores.First());