謝謝大家之前的關注和熱情的回複,本文將繼續探討在System.Linq 下的一些容易被人忽視卻可能對你有大協助的函數。
Empty 靜態方法
有多少次你不得不從一個方法返回一個空集合(無論是由於錯誤的條件,或者沒有項目存在),並建立了一個空數組或列表?
讓我們看一個簡單的POCO 類別,它包含了兩個銀行帳戶轉帳的資訊:
public class Transfer
{
public string FromAccount { get; set; }
public string ToAccount { get; set; }
public double Amount { get; set; }
}
現在,比方說我們有一個Data Access ObjectsData access object,它是用於收集一些特別的轉帳並且返回他們。 但是,如果當轉帳服務正在維護中,我們就返回一個空序列。
我們當然可以返回 空值 NULL ,但返回空序列一般比空值NULL好。 因此,我們這樣做:
public class TransferDao
{
public IEnumerable<Transfer> GetPendingTransfers()
{
if (!_txfrService.IsInMaintenanceMode())
{
// 建立一個列表,並返回它...
}
// 否則,因為我們是在維護模式,返回一個空的集合:
return new List<Transfer>(0);
}
}
這裡的問題是,我們基本上是浪費了記憶體配置。 如果我們打算做的是返回給定類型的唯讀空序列,我們可以使用LINQ的空序列來代表它 -- 盡量不要浪費記憶體配置:
public class TransferDao
{
public IEnumerable<Transfer> GetPendingTransfers()
{
if (!_txfrService.IsInMaintenanceMode())
{
// 建立一個列表,並返回它...
}
// 否則,因為我們是在維護模式,返回一個空的集合:
return Enumerable.Empty<Transfer>();
}
}
請注意,這次我們調用 了 Enumerable 的 Empty<T>() 這個靜態方法,Enumerable 擴充定義了介面 IEnumerable的 方法,Empty 其實只是一個簡單的靜態方法,它傳回型別為 T 的空序列。
DefaultIfEmpty 擴充方法
我們已經會用Empty產生空序列。 但問題是,如果你想返回一個序列當序列是空的時候包含一個預設的項目怎麼辦?
比如說,如果你正在分析測試成績列表,如果學生沒有得分,要返回一個 0:
var scores = new[] { 73, 77, 89, 90, 92, 77 };
foreach (var score in scores.DefaultIfEmpty())
{
Console.WriteLine("The score is: " + score);
}
List<int> emptyScores = new List<int>();
foreach (var score in emptyScores.DefaultIfEmpty())
{
Console.WriteLine("The score is: " + score);
}
現在,還有第二種形式的DefaultIfEmpty(),可讓您指定要使用的預設值,而不是依賴於 Default(T) 。 例如,如果我們希望得到平均分,但如果是空值就要返回一個100.
var averageSoFar = scores.DefaultIfEmpty(100).Average();
Count() 擴充方法
這個方法的作用看起來是顯而易見的,對不對? 在大多數情況下是的。它也有一些不錯的功能,值得一提。
首先,調用 不帶參數的 Count() 返回序列計數。 這可能看起來對於List<T>有點像多餘的:
var scoreArray = new[] { 73, 77, 89, 90, 92, 77 };
var scoreList = new List<int> { 73, 77, 89, 90, 92, 77 };
Console.WriteLine(scoreArray.Length);
Console.WriteLine(scoreArray.Count());
Console.WriteLine(scoreList.Count);
Console.WriteLine(scoreList.Count());
單單的一個 count() , 不是很令人興奮啊。 那麼, 看看它的重載 predicate ( Func<T, bool> ),讓你數算合格所有項目:
var scoreList = new List<int> { 73, 77, 89, 90, 92, 77 };
var numberOfBsOrBetter = scoreList.Count(s => s >= 80);
//為什麼要用這個呢?既然我們有那個方便的重載
var numberOfBsOrBetter = scoreList.Where(s => s >= 80).Count();
Count() VS Any()
該 Count() 擴充方法用於檢查項目的數量,但如果你想知道的是一個序列是不是空,可能更有效是使用Any() 擴充方法。
/ /這個遍曆所有項目,即使第一項已經合乎要求了
var hasAnyBsOrBetter = scoreList.Count(s => s >= 80) != 0;
/ /它將在第一項比較之後就停止,而不進一步檢查
var hasAnyBsOrBetter2 = scoreList.Any(s => s >= 80);
請注意, Any(), 就像 COUNT()一樣,也有不帶參數的形式:
var isEmpty = someSequence.Count() == 0;
var isEmpty2 = !someSequence.Any();
如果序列是類似一個數組列表,可能沒有關係,因為他們需要一個固定的時間 -- 為O(1) -- 來計數,但對於其他序列,使用Any()更有效檢查是否非空。
本文參考翻譯自 C#/.NET Little Wonders: Empty(), DefaultIfEmpty(), and Count()
轉載請註明原出處: 喜樂的ASP.NET(Alex Song)
更多相關文章: http://www.cnblogs.com/multiplesoftware/category/283530.html