[C#.NET] 如果可以 請盡量使用LINQ查詢語法而不是使用迴圈
我相信在for/foreach迴圈絕對是大多數人還在使用的控制結構,假設我有以下的Member類別,_memberList 則是Member類別集合
public struct Member
{
public string Name { get; set; }
public int Age { get; set; }
public List<string> Phones { get; set; }
}
List<Member> _memberList = new List<Member>();
private void Form1_Load(object sender, EventArgs e)
{
this._memberList = new List<Member>()
{
new Member(){Name="Yao",Age=18,Phones=new List<string>(){"0911123456789","0912123456789"}},
new Member(){Name="gy",Age=20,Phones=new List<string>(){"0913123456789","0914123456789"}},
new Member(){Name="LaLa",Age=19,Phones=new List<string>(){"0915123456789","0916123456789"}},
new Member(){Name="9GY",Age=12,Phones=new List<string>(){"0917123456789","0918123456789"}}
};
}
在LINQ還沒有出現以前foreach這是我很常用的查詢方式,比如說我想要查詢集合內的某個屬性,使用foreach迴圈來處理,用來找尋是否有Age大於10的項目
foreach的寫法:
List<Member> query = new List<Member>();
foreach (Member item in this._memberList)
{
if (item.Age > 10)
{
query.Add(item);
}
}
在LINQ裡這麼做:
var find = from data in this._memberList
where data.Age > 10
select data;
foreach (var item in find)
{
//TODO:
}
或是找尋是否有某個關鍵字存在
foreach的寫法:
foreach (var item in this._memberList)
{
if (item.Name.ToUpper() == "YAO")
{
query.Add(item);
}
}
在LINQ裡這麼做:
var find = from data in this._memberList
where data.Name.ToUpper() == "YAO"
select data;
foreach (var item in find)
{
//TODO:
}
在LINQ裡我們的程式語法由"命令式"變成了"聲明式",我們只管下達命令不用管它的實作方式,在閱讀上LINQ優於傳統的for/foreach迴圈
from data in this._memberList →指定資料來源
where data.Age > 10 →條件
select data; →查詢結果
除了閱讀性,還有修改上的彈性,由其是當需求一變動的時候,LINQ則能很快的變動,比如說PM騎著機車要變更需求,找出 "大於10歲" "名字很GY的人" "並且由小到大排序"
foreach的寫法:
List<Member> query = new List<Member>();
foreach (Member item in this._memberList)
{
if (item.Age > 10 && item.Name.ToUpper().IndexOf("GY") >= 0)
{
query.Add(item);
}
}
query.Sort(CompareMember);
int CompareMember(Member a, Member b)
{
return a.Age – b.Age;
}
在LINQ裡這麼做:
var find = from data in this._memberList
where data.Age > 10 && data.Name.ToUpper().IndexOf("GY") >= 0
orderby data.Age
select data;
有沒有發現差異性越來越明顯了,好的,若需求再變更時程式碼會有什麼變化呢!?這時開著卡車來的PM,要求找出特定的電話號碼 0917123456789
foreach的寫法:
巢狀迴圈的寫法越讀起來越來越吃力了,好吧!!或許有人會說我把巢狀迴圈拆開不就好了,就算拆開也沒有辦法像LINQ那麼乾淨,對吧!?
List<Member> query = new List<Member>();
foreach (Member item in this._memberList)
{
if (item.Age > 10 && item.Name.ToUpper().IndexOf("GY") >= 0)
{
foreach (string phone in item.Phones)
{
if (phone == "0917123456789")
{
query.Add(item);
}
}
}
}
query.Sort(CompareMember);
LINQ裡這麼做:
var find = from data in this._memberList
where data.Age > 10
where data.Name.ToUpper().IndexOf("GY") >= 0
orderby data.Age
from phone in data.Phones
where phone == "0917123456789"
select data;
後記:
雖然LINQ效能並沒有想像中的好,不過它的查詢功能的可讀性以及修改彈性都很高,在上面的例子我會捨棄效能來迎合這樣的閱讀性及修改彈性,所以如果可以我都會盡可能的使用LINQ。
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET