Effective C# (Covers C# 6.0), (includes Content Update Program): 50 Specific Ways to Improve Your C#, 3rd Edition By Bill Wagner 讀後心得
LINQ 讓我們很方便的可以操作集合,然而,LINQ 也可以幫助我們寫出更能表達意圖的程式。
Single():當搜尋條件超過一筆或沒有符合條件的結果時擲出例外,早期的擲出例外可以避免後許程式碼有不正常的行為(例如:寫入不正確的資料)。Single() 語意本身也很清楚的表明只要得到唯一元素而非集合。
SingleOrDefault():當搜尋條件超過一筆時擲出例外,而沒有符合條件的結果時回傳元素預設值(參考型別為 null)。當可允許搜尋不到結果時使用。
範例:
var somePeople = new List<Person>
{
new Person{FirstName="Bill", LastName="Gates"},
new Person{FirstName="Bill", LastName="Wagner"},
new Person{FirstName="Bill", LastName="Johnson"}
}
// 集合不只一筆資料符合條件,丟出例外。
var answer = (from p in somePeople
where p.FirstName == "Bill"
select p).Single();
// 集合沒有資料符合條件,丟出例外。
var answer2 = (from p in somePeople
where p.FirstName == "Larry"
select p).Single();
// 回傳 null
var answer3 = (from p in somePeople
where p.FirstName == "Larry"
select p).SingleOrDefault();
First():取得第一個符合條件的元素,若沒有符合條件的結果則擲出例外;可以搭配 Skip() 或 orderby 取得對應元素。
FirstOrDefault():取得第一個符合條件的元素,若沒有符合條件的結果則回傳元素預設值。當可允許搜尋不到結果時使用。
範例:
var forwards = new List<Forward>
{
new Forward{GoalsScored=20},
new Forward{GoalsScored=10},
new Forward{GoalsScored=5},
};
var answer4 = (from f in forwards
where f.GoalsScored > 0
orderby f.GoalsScored
select f).FirstOrDefault();
// 若沒有符合條件的資料,擲出例外。
var answer5 = (from f in forwards
where f.GoalsScored > 0
orderby f.GoalsScored
select f).First();
// 這裡不用 Take,原因是想取的值是單一個元素,而非整個集合。
var answer6 = (from f in forwards
where f.GoalsScored > 0
orderby f.GoalsScored
select f).Skip(2).First(); // 取得第三個值
使用 Skip() 時語意已經相較不清楚。有使用 Skip() 需求時,應考慮是否使用支援索引的 IList<T> 直接對索引存取;或修改搜尋邏輯,讓回傳結果唯一。
結論:
1. 善加利用 Single(), SingleOrDefault(), First(), FirstOrDefault() 回傳元素,讓語意更加貼近實際需求。
1. 善加利用 Single(), SingleOrDefault(), First(), FirstOrDefault() 回傳元素,讓語意更加貼近實際需求。