C#的十種語法糖介紹
語法糖
指計算機(jī)語言中添加的某種語法,這種語法對語言的功能并沒有影響,但是更方便程序員使用。通常來說使用語法糖能夠增加程序的可讀性,從而減少程序代碼出錯的機(jī)會。
需要聲明的是“語法糖”這個詞絕非貶義詞,它可以給我們帶來方便,是一種便捷的寫法,編譯器會幫我們做轉(zhuǎn)換,而且可以提高開發(fā)編碼的效率,在性能上也不會帶來損失。
一、自動屬性
以前:手寫私有變量+公有屬性
現(xiàn)在:聲明空屬性,編譯器自動生成對應(yīng)私有成員字段。
寫法:輸入prop ,連續(xù)按兩次tab鍵,自動生成屬性。
/// <summary> /// 自動屬性 /// </summary> public string Name { get; set; } /// <summary> /// 傳統(tǒng)屬性寫法 /// </summary> private string _LoginName; public string LoginName { get { return _LoginName; } set { _LoginName = value; } }
二、隱式類型(var)
var定義變量有以下四個特點:
程序員在聲明變量時可以不指定類型,由編譯器根據(jù)值來指定類型
- 1、必須在定義時初始化
- 2、一旦初始化完成,就不能再給變量賦與初始值不同類型的值了
- 3、var要求是局部變量
- 4、使用var定義變量和object不同,它在效率上和使用強(qiáng)類型方式定義變量完全一樣
注意:
a.隱式類型在定義時必須初始化
例如:var name; 錯 var name="Tom";正確
b.可以用同類型的其他隱式類型變量來初始化新的隱式類型變量
例如:var v=1;
var v2=v;
c.也可以用同類型的字面量來初始化隱式類型變量
例如: var v3="hello";
v3="world";
d.隱式類型局部變量還可以初始化數(shù)組而不指定類型
例如: var array=new int[]{1,2,3,4,5}; (注意:賦值運算符左邊沒有方括號)
e.編譯器可以根據(jù)變量的初始值“推斷”變量的類型
例如: var number=0; 編譯后就變成了 int number =0;
三、參數(shù)默認(rèn)值和命名參數(shù)
C#方法的可選參數(shù)是.net 4.0最新提出的新的功能,對應(yīng)簡單的重載可以使用可選參數(shù)和命名參數(shù)混合的形式來定義方法,這樣就可以很高效的提高代碼的運行效率
設(shè)計一個方法的參數(shù)時,可以部分或全部參數(shù)分配默認(rèn)值。調(diào)用其方法時,可以重新指定分配了默認(rèn)值的參數(shù),也可以使用默認(rèn)值。重新指定分配默認(rèn)值的參數(shù)時,可以顯式地為指定參數(shù)名稱賦值;隱式指定的時候,是根據(jù)方法參數(shù)的順序,靠C#編譯器的推斷。
使用的指導(dǎo)原則:
- 1、可以為方法和有參屬性指定默認(rèn)值
- 2、有默認(rèn)值的參數(shù),必須定義在沒有默認(rèn)值的參數(shù)之后
- 3、默認(rèn)參數(shù)必須是常量
- 4、ref和out參數(shù)不能指定默認(rèn)值
public class User { /// <summary> /// 自動屬性 /// </summary> public string Name { get; set; } public string LoginName { get; set; } public int Age { get; set; } public string Address { get; set; } public string Password { get; set; } //構(gòu)造函數(shù)重載 public User(string name) { this.Name = name; } public User(string name,string loginName) { this.Name = name; this.LoginName = loginName; } /// <summary> /// 默認(rèn)參數(shù) /// </summary> /// <param name="name"></param> /// <param name="loginName"></param> /// <param name="age"></param> /// <param name="address"></param> /// <param name="password"></param> public User(string name,string loginName,int age,string address="上海",string password="1234") { this.Name = name; this.LoginName = loginName; this.Age = age; this.Address = address; this.Password = password; } } 使用默認(rèn)值參數(shù)和命名參數(shù) class Program { static void Main(string[] args) { //參數(shù)默認(rèn)值:可以給參數(shù)賦值也可以使用參數(shù)默認(rèn)值 //1、使用默認(rèn)值 User user = new User("小明","xiaoming",27); Console.WriteLine(user.Address);//輸出默認(rèn)值:上海 //2、給參數(shù)賦值 User user2 = new User("小紅", "xiaohong", 28,"北京"); Console.WriteLine(user2.Address);//輸出:北京 //命名參數(shù):使用默認(rèn)值參數(shù)的時候,指定參數(shù)的名稱,命名參數(shù)要寫在所有固定參數(shù)的后面 //好處:適用于有多個默認(rèn)值參數(shù)的情況,根據(jù)命名參數(shù),只修改需要修改的默認(rèn)值 //使用命名參數(shù)只修改密碼 User user3 = new User("小紅", "xiaohong", 28,password:"5678"); Console.WriteLine(user3.Password);//輸出:5678 Console.ReadKey(); } }
輸出結(jié)果:
四、對象初始化器和集合初始化器
class Program { static void Main(string[] args) { //傳統(tǒng)的初始化對象的方式 User zjl = new User(); zjl.Name = "周杰倫"; zjl.phone = "12345678956"; //使用對象初始化器:{},使用對象初始化器,必須提供一個無參的構(gòu)造函數(shù),可以只給部分屬性初始化 User xiaohong = new User() { Name = "小紅", phone = "1232154566", Address = "上海" }; Console.WriteLine("姓名:"+xiaohong.Name);//輸出:小紅 //集合初始化器 List<User> listUser = new List<User>() { xiaohong, new User(){Name="張三",Password="1234",Age=12,DeptId="0001"}, new User(){Name="張四",Password="1234",Age=16,DeptId="0002"}, new User(){Name="張五",Password="1234",Age=29,DeptId="0003"}, new User(){Name="張六",Password="1234",Age=18,DeptId="0001"}, new User(){Name="張七",Password="1234",Age=12,DeptId="0001"} }; Console.ReadKey(); } }
五、匿名類和匿名方法
匿名類型
有時候你定義的類只是用來封裝一些相關(guān)的數(shù)據(jù),但并不需要相關(guān)聯(lián)的方法、事件和其他自定義的功能。同時,這個類僅僅在當(dāng)前的應(yīng)用程序中使用,而不需要在項目間重用。你所需要的只是一個“臨時的”類型,現(xiàn)在來看看這個類的定義
internal class oneClass { ?? //定義若干私有數(shù)據(jù)成員 ?? //通過屬性來封裝每個數(shù)據(jù)成員 }
構(gòu)建上面的類雖然說不上有多難,但是如果這個類有很多數(shù)據(jù)成員的話,那么還是要消耗相當(dāng)時間的。C#3.0提供了匿名類型來輕松完成這個工作。
現(xiàn)在定義一個匿名對象來表示一個人
var aPeople=new {pName="張三",pAge=26,pSex="男"};
現(xiàn)在我們就可以使用屬性語法獲取和設(shè)置對象的各個變量
aPeople.pAge=29; Console.WriteLine("{0} is {1}years old",aPeople.pName,aPeople.pAge);
匿名類型的嵌套
剛剛我們定義了表示一個人的匿名類型,現(xiàn)在我們定義一個表示雇員的嵌套匿名類型:
??? var Aemployee=new { ??????? JoinDate="2012-09-23", ??????? aPeople=new {pName="張三",pAge=26,pSex="男"}, ??????? title=Manager ??? };
匿名類型的限制:
- 1、匿名類型不支持事件、自定義方法和自定義重寫
- 2、匿名類型是隱式封閉的
- 3、匿名類型的實例創(chuàng)建只使用默認(rèn)構(gòu)造函數(shù)
- 4、匿名類型沒有提供可供控制的類名稱(使用var定義的)
匿名方法
普通方法定義方式,因為方法的存在是為了復(fù)用一段代碼,所以一般會給方法取個名字,這個方法的引用就可以通過“方法名”調(diào)用
匿名方法:
但是有的方法,不需要復(fù)用,僅僅是使用一次就夠了,所以不需要方法名,這種方法就叫做匿名方法。
匿名方法必須結(jié)合委托使用。(潛在的意思就是:盡管沒有方法名了,但方法的指針還是存放了某個委托對象中)
注意:
- 1、在編譯后,會為每個匿名方法創(chuàng)建一個私有的靜態(tài)方法,然后將此靜態(tài)方法傳給委托對象使用
- 2、匿名方法編譯后會生成委托對象,生成方法,然后把方法裝入委托對象,最后賦值給聲明的委托變量
- 3、匿名方法可以省略參數(shù),編譯的時候會自動為這個方法按照委托簽名的參數(shù)添加參數(shù)
public class Test { public static void TestFive() { //匿名類型:只能使用一次,僅能在當(dāng)前的項目中使用 var aPeople = new { pName = "張三", pAge = 26, pAddress = "美國" }; //嵌套匿名類型 var aEmployee = new { JionDate = DateTime.Now, Salary = 8000, aPeople = new { pName = "張三", pAge = 26, pAddress = "美國" } }; Console.WriteLine(aEmployee.aPeople.pName);//輸出:張三 Console.ReadKey(); } public static void Test() { //不能使用匿名類型aPeople,aPeople是局部 Console.WriteLine(aPeople.pName);//錯誤 } }
匿名方法
class Program { /// <summary> /// 聲明委托 /// </summary> /// <param name="s"></param> delegate void Printer(string s); public delegate void PrintEmployee(User u); static void Main(string[] args) { //匿名方法:必須結(jié)合委托使用 Printer p = delegate(string s) { Console.WriteLine(s); }; //使用匿名方法 p("Hello World"); List<User> listUser = new List<User>() { new User(){Name="張三",Password="1234",Age=12,DeptId="0001"}, new User(){Name="張四",Password="1234",Age=16,DeptId="0002"}, new User(){Name="張五",Password="1234",Age=29,DeptId="0003"}, new User(){Name="張六",Password="1234",Age=18,DeptId="0001"}, new User(){Name="張七",Password="1234",Age=12,DeptId="0001"} }; //匿名方法只使用一次 ChangeUserPwd(listUser, delegate(User u) { Console.WriteLine(u.Name+"的新密碼是:"+u.Password); }); //使用Lambda表達(dá)式 ChangeUserPwd(listUser, u=> { Console.WriteLine(u.Name + "的新密碼是:" + u.Password); }); Console.ReadKey(); } /// <summary> /// 批量修改用戶的密碼并輸出修改以后的密碼 /// </summary> /// <param name="list"></param> /// <param name="callback"></param> public static void ChangeUserPwd(List<User> list, PrintEmployee callback) { int i = 0; foreach (User u in list) { u.Password = u.Password + i.ToString(); i += 2; callback(u); } } }
六、擴(kuò)展方法
為什么要有擴(kuò)展方法,就是為了在不修改源碼的情況下,為某個類增加新的方法。
語法:
定義靜態(tài)類,并添加public的靜態(tài)方法,第一個參數(shù)代表擴(kuò)展方法的擴(kuò)展類。它必須放在一個非嵌套、非泛型的靜態(tài)類中(的靜態(tài)方法);它至少有一個參數(shù);第一個參數(shù)必須附加this關(guān)鍵字;第一個參數(shù)不能有任何其他修飾符(out/ref).第一個參數(shù)不能是指針類型。
注意:
- 1、C#只支持?jǐn)U展方法,不支持?jǐn)U展屬性、擴(kuò)展事件等;
- 2、方法名無限制,第一個參數(shù)必須帶this,表示要擴(kuò)展的類型;
- 3、擴(kuò)展方法的命名空間可以使用namespace System,但不推薦;
- 4、定義擴(kuò)展方法的類必須是靜態(tài)類;
- 5、擴(kuò)展方法雖然是public的靜態(tài)方法,但是生成以后是實例方法,使用時需要先實例化對象,通過對象.方法名進(jìn)行調(diào)用擴(kuò)展方法;
/// <summary> /// 靜態(tài)類:對Convert進(jìn)行擴(kuò)展,增加一個將string轉(zhuǎn)換成int的方法 /// </summary> public static class ConvertExtension { /// <summary> /// 靜態(tài)方法:this 表示針對this后面的類型進(jìn)行擴(kuò)展 /// </summary> /// <param name="s"></param> /// <returns></returns> public static int ConvertToInt(this Convert convert,string s) { int i; if (int.TryParse(s, out i)) { return i; } else { return 0; } } } class Program { static void Main(string[] args) { //使用擴(kuò)展方法:擴(kuò)展方法雖然是public的靜態(tài)方法,但是生成以后是實例方法,使用時需要先實例化對象,通過對象.方法名進(jìn)行調(diào)用擴(kuò)展方法 //擴(kuò)展方法所在命名空間和使用代碼的命名空間必須相同 擴(kuò)展方法必須是靜態(tài)類 Convert convert = new Convert(); int i= convert.ConvertToInt("abc"); Console.WriteLine(i);//輸出:0 //方法2 int j= ConvertExtension.ConvertToInt(convert, "2"); Console.WriteLine(j);//輸出:2 Console.ReadKey(); } }
七、內(nèi)置泛型委托
Action<T>
可以使用Action<T>委托以參數(shù)形式傳遞方法,而不用顯示聲明自定義的委托。封裝的方法必須與此委托定義的方法簽名相對應(yīng),也就是說,封裝的方法必須具有一個通過值傳遞給它的參數(shù),并且不能有返回值。
通常,這種方法用于執(zhí)行某個操作。
/// <summary> /// List擴(kuò)展方法 /// </summary> public static class ListExtend { //聲明自定義泛型委托 public delegate void PrintT<T>(T t); public static void TEach<T>(this List<T> list, PrintT<T> pt) { foreach (T t in list) { pt(t); } } } class Program { static void Main(string[] args) { List<User> listUser = new List<User>() { new User(){Name="張三",Password="1234",Age=12,DeptId="0001"}, new User(){Name="張四",Password="1234",Age=16,DeptId="0002"}, new User(){Name="張五",Password="1234",Age=29,DeptId="0003"}, new User(){Name="張六",Password="1234",Age=18,DeptId="0001"}, new User(){Name="張七",Password="1234",Age=12,DeptId="0001"} }; List<Dept> listDept = new List<Dept>() { new Dept(){DeptId="0001",DeptName="人事部",PepNum=10}, new Dept(){DeptId="0002",DeptName="財務(wù)部",PepNum=7}, new Dept(){DeptId="0003",DeptName="行政部",PepNum=15} }; #region 使用自定義委托 //打印所有用戶信息 listUser.TEach(PrintUser); listDept.TEach(PrintDept); #endregion #region 使用內(nèi)置泛型委托 listUser.ForEach(PrintUser); //使用匿名方法 listUser.ForEach(delegate(User u) { Console.WriteLine(u.Name + " " + u.Password + " " + u.phone); }); //使用Lambda表達(dá)式 listUser.ForEach(p=>Console.WriteLine(p.Name+" "+p.Password+" "+p.phone)); listDept.ForEach(new Action<Dept> (delegate(Dept d) { Console.WriteLine(d.DeptId + " " + d.DeptName + " " + d.PepNum); })); #endregion Console.ReadKey(); } /// <summary> /// 打印一個用戶信息 /// </summary> /// <param name="u"></param> public static void PrintUser(User u) { Console.WriteLine(u.Name+" "+u.Password+" "+u.phone); } /// <summary> /// 打印一個部門信息 /// </summary> /// <param name="d"></param> public static void PrintDept(Dept d) { Console.WriteLine(d.DeptId+" "+d.DeptName+" "+d.PepNum); } }
Predicate<T>
表示定義一組條件并確定指定對象是否符合這些條件的方法。
此委托由Array和List<T>類的幾種方法使用,用于在集合中搜索元素。返回值為Bool類型
public static class Extend { //自定義泛型委托 public delegate bool CheckDelegate<T>(T t); public static List<T> MyFind<T>(this List<T> list, CheckDelegate<T> match) { List<T> newList = new List<T>(); foreach (T item in list) { if (match(item)) { newList.Add(item); } } return newList; } } class Program { static void Main(string[] args) { List<User> listUser = new List<User>() { new User(){Name="張三",Password="1234",Age=12,DeptId="0001"}, new User(){Name="張四",Password="1234",Age=16,DeptId="0002"}, new User(){Name="張五",Password="1234",Age=29,DeptId="0003"}, new User(){Name="張六",Password="1234",Age=18,DeptId="0001"}, new User(){Name="張七",Password="1234",Age=12,DeptId="0001"} }; List<Dept> listDept = new List<Dept>() { new Dept(){DeptId="0001",DeptName="人事部",PepNum=10}, new Dept(){DeptId="0002",DeptName="財務(wù)部",PepNum=7}, new Dept(){DeptId="0003",DeptName="行政部",PepNum=15} }; //使用內(nèi)置Predicate委托 List<User> newListUser= listUser.FindAll(new Predicate<User>(delegate(User u){return u.Age>40;})); //使用自定義泛型委托 List<User> list = listUser.MyFind(Match); foreach (User u in list) { Console.WriteLine(u.Name + " " + u.Password + " " + u.phone); } Console.ReadKey(); } static bool Match(User u) { if (u.Age > 15) { return true; } return false; } }
Func 返回值類型可以自定義
class Program { static void Main(string[] args) { List<User> listUser = new List<User>() { new User(){Name="張三",Password="1234",Age=12,DeptId="0001"}, new User(){Name="張四",Password="1234",Age=16,DeptId="0002"}, new User(){Name="張五",Password="1234",Age=29,DeptId="0003"}, new User(){Name="張六",Password="1234",Age=18,DeptId="0001"}, new User(){Name="張七",Password="1234",Age=12,DeptId="0001"} }; List<Dept> listDept = new List<Dept>() { new Dept(){DeptId="0001",DeptName="人事部",PepNum=10}, new Dept(){DeptId="0002",DeptName="財務(wù)部",PepNum=7}, new Dept(){DeptId="0003",DeptName="行政部",PepNum=15} }; //可以自定義Func返回值類型 List<int> newList= listUser.Select(new Func<User, int>(delegate(User u) { return u.Age; })).ToList(); List<int> list = listUser.Select(p => { return p.Age; }).ToList(); newList.ForEach(p => Console.WriteLine(p)); //根據(jù)用戶信息得到員工信息 List<Employee> listEmploy= listUser.Select(new Func<User, Employee>(delegate(User u) { Employee e = new Employee(); if (u.Age > 15) { e.Name = u.Name; e.Phone = u.phone; e.Salary = 5000; return e; } else { return null; } })).ToList(); listEmploy.ForEach(p => { if (p != null) { Console.WriteLine(p.Name+" "+p.Salary); } }); Console.ReadKey(); } }
八、Lambda表達(dá)式
Lambda表達(dá)式是比匿名方法更簡潔的一種匿名方法語法
最基本的Lambda表達(dá)式語法:
{參數(shù)列表}=>{方法體}
例如:
(int x)=>{returm x+1}
說明:
1、參數(shù)列表中的參數(shù)類型可以是明確類型或推斷類型
2、如果是推斷類型,則參數(shù)的數(shù)據(jù)類型將由編譯器根據(jù)上下文自動推斷出來
如果參數(shù)列表只包含一個推斷類型參數(shù)時:
參數(shù)列表=>{方法體}
前提:x的數(shù)據(jù)類型可以根據(jù)上下文推斷出來
x =>{returm x+1}
如果方法體只包含一條語句時:
{參數(shù)列表}=>表達(dá)式
{int x} => x+1;
Lambda表達(dá)式示例:
1、多參數(shù),推斷類型參數(shù)列表,表達(dá)式方法體
(x,y) => x*y
2、無參數(shù),表達(dá)式方法體
() => Console.WriteLine()
3、多參數(shù),推斷類型參數(shù)列表,多語句方法體,需要使用{}
(x,y) => {Console.WriteLine(x);Console.WriteLine(y)}
Lambda表達(dá)式縮寫推演
new Func<string,int>(delegate(string str){return str.Length;});//內(nèi)置委托
delegate(string str){return str.Length;}//匿名方法
(string str)=>{return str.Length};//Lambda表達(dá)式
(str)=>str.Length;//讓編譯器推斷類型
str=>str>Length;//去掉不必要的括弧
#region Lambda表達(dá)式 //標(biāo)準(zhǔn)語法 MyDelegate my1 = (string name) => { return "Lambda表達(dá)式:hello" + name; }; Console.WriteLine(my1("tom")); //或者(僅有一個參數(shù)) 參數(shù)列表只包含一個推斷類型參數(shù) MyDelegate my2 = name => { return "Lambda表達(dá)式:hello" + name; }; Console.WriteLine(my2("tom")); //或者(方法體只有一條語句) MyDelegate my3 = name => "Lambda表達(dá)式:hello" + name; Console.WriteLine(my3("tom")); #endregion
九、標(biāo)準(zhǔn)查詢運算符
標(biāo)準(zhǔn)查詢運算符:定義在System.Linq.Enumerable類中的50多個為IEnumerable<T>準(zhǔn)備的擴(kuò)展方法,這些方法用來對它操作的集合進(jìn)行查詢篩選。
篩選集合where:需要提供一個帶bool返回值的“篩選器”,從而標(biāo)明集合中某個元素是否應(yīng)該被返回。
查詢投射:返回新對象集合IEnumerable<TSource> Select()
統(tǒng)計數(shù)量int Count()
多條件排序 OrderBy().ThenBy().ThenBy()
集合連接 Join()
class Program { static void Main(string[] args) { List<User> listUser = new List<User>() { new User(){Name="張三",Password="1234",Age=12,DeptId="0001"}, new User(){Name="張四",Password="1234",Age=16,DeptId="0002"}, new User(){Name="張五",Password="1234",Age=29,DeptId="0003"}, new User(){Name="張六",Password="1234",Age=18,DeptId="0001"}, new User(){Name="張七",Password="1234",Age=12,DeptId="0001"} }; List<Dept> listDept = new List<Dept>() { new Dept(){DeptId="0001",DeptName="人事部",PageNum=10}, new Dept(){DeptId="0002",DeptName="財務(wù)部",PageNum=10}, new Dept(){DeptId="0003",DeptName="行政部",PageNum=10} }; //1.where List<User> newListUser = listUser.Where(p => p.Age>12).ToList(); Console.WriteLine("所有用戶姓名"); listUser.ForEach(p=>Console.WriteLine(p.Name)); Console.WriteLine("年齡大于12的用戶姓名"); newListUser.ForEach(p=>Console.WriteLine(p.Name)); //2.order by 排序 多條件排序:先按照年齡降序排序,在安排phone降序排序,最后按照LoginName升序排序 List<User> list1 = listUser.OrderByDescending(p => p.Age).ThenByDescending(p => p.phone).ThenBy(p => p.LoginName).ToList(); //3.join:連接查詢 //返回值是非匿名類:返回值是UserDept類型 List<UserDept> uds = listUser.Join(listDept, u => u.DeptId, d => d.DeptId, (u, d) => new UserDept() { UserName = u.Name, LoginName = u.LoginName, DeptName = d.DeptName }).ToList(); //循環(huán)輸出 uds.ForEach(p=>Console.WriteLine(p.UserName)); //返回值是匿名類:用var推斷類型接收返回值 var udVar = listUser.Join(listDept, u => u.DeptId, d => d.DeptId, (u, d) => new { UserName = u.Name, LoginName = u.LoginName, DeptName = d.DeptName }).ToList(); //循環(huán)輸出 udVar.ForEach(p => Console.WriteLine(p.UserName)); #region 4.0 group by 分組 //4.1 按照集合中的用戶的部門編號進(jìn)行分組 IEnumerable<IGrouping<string, User>> userGroup = listUser.GroupBy(p => p.DeptId); foreach (IGrouping<string, User> group in userGroup) { Console.WriteLine("部門編號:" + group.Key); foreach (User user in group) { Console.WriteLine(user.Name + "-" + user.phone + "-" + user.LoginName); } Console.WriteLine("--------------------------------"); } #endregion #region 5.0 分頁:Skip+Take Skip:跳過 Take:取 //分頁前提:數(shù)據(jù)源按照一定的列進(jìn)行排序 List<User> listSource = listUser.OrderBy(p => p.Name).ToList(); foreach (User user in listSource) { Console.WriteLine(user.Name); } Console.WriteLine("--------------"); //取第一頁數(shù)據(jù),每頁顯示2條數(shù)據(jù) List<User> list = GetPageListByIndex(listUser, 1, 2); //輸出分頁結(jié)果 foreach (User user in list) { Console.WriteLine(user.Name); } #endregion Console.ReadKey(); } /// <summary> /// 根據(jù)頁碼提取當(dāng)頁數(shù)據(jù) /// </summary> /// <param name="listSource">要分頁的數(shù)據(jù)</param> /// <param name="pageIndex">頁碼</param> /// <param name="pageSize">每頁要顯示的條數(shù)</param> /// <returns></returns> static List<User> GetPageListByIndex(List<User> listSource, int pageIndex, int pageSize) { return listSource.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList(); } }
十、Linq
Linq:語言集成查詢
Linq是一組語言特性和API,使得你可以使用統(tǒng)一的方式編寫各種查詢。查詢的對象包括XML、對象集合、SQL Server數(shù)據(jù)庫等等。
Linq to Objects:主要負(fù)責(zé)對象的查詢
Linq to XML:主要負(fù)責(zé)XML的查詢
Linq to ADO.NET:主要負(fù)責(zé)數(shù)據(jù)庫的查詢
Linq to SQL
Linq to DataSet
Linq to Entities
Linq查詢的兩種方式:
1、查詢方法方式:主要利用System.Linq.Enumerable類中定義的擴(kuò)展方法和Lambda表達(dá)式進(jìn)行查詢
2、查詢語句方式:一種更接近SQL語法的查詢方式
查詢語句VS查詢方法
1、CLR本身并不理解查詢語句,它只理解查詢方法
2、編譯器負(fù)責(zé)在編譯時將查詢語句翻譯成查詢方法
3、大部分查詢方法都有對應(yīng)的查詢語句形式:Select()對應(yīng)select、OrderBy()對應(yīng)orderby
4、部分查詢方法目前在C#中還沒有對應(yīng)的查詢語句,如:Count()和Max()這時只能采用以下替代方案:
查詢方法
查詢語句+查詢方法的混合方式
class Program { //聲明委托 public delegate string MyDelegate(string name); static void Main(string[] args) { //創(chuàng)建int類型數(shù)組,查找其中的偶數(shù)并降序排序輸出 int[] arrays = { 5, 2, 0, 66, 4, 32, 7, 1 }; #region 使用循環(huán)實現(xiàn) List<int> list = new List<int>(); foreach (int i in arrays) { if (i % 2 == 0) { list.Add(i); } } //排序 list.Sort(); //反轉(zhuǎn) list.Reverse(); Console.WriteLine(string.Join(",", list)); #endregion #region 使用Linq實現(xiàn) //查詢方法方式 var intNew = arrays.Where(p => p % 2 == 0) .Select(p => p) .OrderByDescending(p => p).ToList(); Console.WriteLine(string.Join(",", intNew)); //查詢語句方式 var even = from number in arrays where number % 2 == 0 orderby number descending select number; #endregion //Linq新特性 #region 類型推斷 //類型推斷 注意:不要亂用,僅用在Linq中 var b = true; if (b) { Console.WriteLine("True"); } #endregion #region 擴(kuò)展方法 //擴(kuò)展方法 擴(kuò)展方法所在命名空間和使用代碼的命名空間必須相同 擴(kuò)展方法必須是靜態(tài)類 string s = "abc"; int a = s.ToInt();//方法圖標(biāo)有一個向下的箭頭,表示是擴(kuò)展方法 Console.WriteLine(a); object obj = "sdsf"; double d= obj.ToDouble(); Console.WriteLine(d); #endregion #region 對象初始化器 //集合初始化器 Contact con = new Contact() {FirstName="Tom",LastName="Jerry",Email="tom@163.com" }; Console.WriteLine(con.Email); #endregion #region 集合初始化器 List<Contact> listContact = new List<Contact>() { new Contact(){FirstName="Tom",LastName="Tack",Email="aaa"}, new Contact(){FirstName="Tom",LastName="jerry",Email="bbb"} }; Console.WriteLine(listContact[0].Email); #endregion #region 匿名類型 var item = new {ProductName="Iphone",Price=4000 }; string info = item.ProductName + "..." + item.Price; Console.WriteLine(info); #endregion //定義委托類型的變量 MyDelegate my = new MyDelegate(Hello);//MyDelegate my=Hello //調(diào)用委托 string strName = my("tom"); Console.WriteLine(strName); #region 匿名方法(只用一次) MyDelegate my2 = delegate(string str) { return "匿名方法:hello" + str; }; //調(diào)用 string name= my2("tom"); Console.WriteLine(name); #endregion #region Lambda表達(dá)式 //標(biāo)準(zhǔn)語法 MyDelegate my1 = (string str) => { return "Lambda表達(dá)式:hello" + str; }; Console.WriteLine(my1("tom")); //或者(僅有一個參數(shù)) 參數(shù)列表只包含一個推斷類型參數(shù) MyDelegate myDel = p => { return "Lambda表達(dá)式:hello" + p; }; Console.WriteLine(my2("tom")); //或者(方法體只有一條語句) MyDelegate my3 = p => "Lambda表達(dá)式:hello" + p; Console.WriteLine(my3("tom")); #endregion //Linq //兩種查詢方式 //Select int[] intArray = { 1,2,3,6,4,90,65,44,9}; //1、查詢方法方式 p:指的是intArray數(shù)組中的每一個元素 var var1 = intArray.Select(p => p + 1); Console.WriteLine(string.Join(",", var1)); //2、查詢語句方式 var var2 = from p in intArray select p + 1; Console.WriteLine(string.Join(",", var1)); //where //查詢方法 var var3 = intArray.Where(p => p % 2 == 0);//選擇數(shù)組中的偶數(shù) //查詢語句(一般以select結(jié)尾) var3 = from number in intArray where number % 2 == 0 select number; //多個條件(刷選出數(shù)組中大于10的偶數(shù)) //查詢方法1 var3 = intArray.Where(p => p % 2 == 0 && p > 10); //查詢方法2:使用自定義謂語條件查詢 var3 = intArray.Where(p => GetCondition(p)); //查詢語句1 var3 = from number in intArray where number % 2 == 0 && number > 10 select number; //查詢語句2 var3 = from number in intArray where GetCondition(number) select number; Console.WriteLine(string.Join(",", var3)); //建立一個Contact類型的集合,查找FirstName="tom" && email=""的聯(lián)系人的LastName,使用4種方式查詢 List<Contact> MyContact = new List<Contact>() { new Contact(){FirstName="tom",LastName="jorry",Email="Tom@163.com"}, new Contact(){FirstName="tom",LastName="jack",Email="jack@163.com"}, new Contact(){FirstName="tom",LastName="jerry",Email="jerry@163.com"} }; //查詢方法 var var4 = MyContact.Where(p => p.FirstName == "tom" && p.Email == "Tom@163.com"); var4 = MyContact.Where(p => GetContact(p)); //查詢語句 var4 = from p in MyContact where p.FirstName == "tom" && p.Email == "Tom@163.com" select p; var4 = from p in MyContact where GetContact(p) select p; foreach(Contact contact in var4) { Console.WriteLine(contact.LastName); } //刪除重復(fù)元素,沒有對應(yīng)的查詢語句 int[] ints = { 1,1,2,3,4,0}; var var5 = ints.Distinct(); Console.WriteLine(string.Join(",",var5)); //排序 int[] intArrays = { 1,2,4,3,7,8,0}; var var6 = intArrays.OrderBy(i => i); var6 = intArrays.OrderByDescending(i => i); //級聯(lián)調(diào)用 var6 = intArrays.Where(i => i % 2 == 0).OrderBy(i => i); var6 = from i in intArrays where i % 2 == 0 orderby i select i;//正序排序 var6 = from i in intArrays where i % 2 == 0 orderby i descending select i;//倒序排序 //查詢方法+查詢語句,混合使用 var6 = (from i in intArrays where i % 2 == 0 select i).OrderBy(i => i); Console.WriteLine(string.Join(",", var6)); //復(fù)雜查詢 List<Employee> listEmployee = new List<Employee>() { new Employee(){ FirstName="唐僧", LastName="玄奘", Sex="男", Age=30, Country="大唐" }, new Employee(){ FirstName="白骨精", LastName="晶晶", Sex="女", Age=200, Country="古墓" }, new Employee(){ FirstName="孫悟空", LastName="行者", Sex="男", Age=500, Country="傲來國" }, new Employee(){ FirstName="紫霞", LastName="仙子", Sex="女", Age=100, Country="天界" } }; //分組,按照性別分組 var var7 = from p in listEmployee group p by p.Sex; var7 = listEmployee.GroupBy(p => p.Sex); foreach (var group in var7) { Console.WriteLine("分組:"+group.Key); foreach (var v in group) { Console.WriteLine(v.FirstName); } } Console.ReadKey(); } static bool GetContact(Contact item) { if (item.FirstName == "tom" && item.Email == "Tom@163.com") return true; else return false; } static bool GetCondition(int i) { if (i % 2 == 0 && i > 10) return true; else return false; } static string Hello(string name) { return "hello" + name; } }
查詢語句
class Program { static void Main(string[] args) { List<User> listUser = new List<User>() { new User(){Name="張三",Password="1234",Age=12,DeptId="0001"}, new User(){Name="張四",Password="1234",Age=16,DeptId="0002"}, new User(){Name="張五",Password="1234",Age=29,DeptId="0003"}, new User(){Name="張六",Password="1234",Age=18,DeptId="0001"}, new User(){Name="張七",Password="1234",Age=12,DeptId="0001"} }; List<Dept> listDept = new List<Dept>() { new Dept(){DeptId="0001",DeptName="人事部",PageNum=10}, new Dept(){DeptId="0002",DeptName="財務(wù)部",PageNum=10}, new Dept(){DeptId="0003",DeptName="行政部",PageNum=10} }; //1、從老集合中查詢每一個元素存放到新集合 var newList = from p in listUser select p; //2、帶where條件 var list = from p in listUser where p.Age > 12 && p.Address == "上海" select p; //3、OrderBy排序:按照姓名、年齡升序排序 var newListUser = from p in listUser orderby p.Name orderby p.Age ascending select p; //4、Join var joinResult = from u in listUser join d in listDept on u.DeptId equals d.DeptId select new {UserName = u.Name, LoginName = u.LoginName, DeptName = d.DeptName }; //遍歷 foreach (var item in joinResult) { Console.WriteLine(item.DeptName); } //5、 group by 分組查詢 var groupList = from u in listUser group u by u.DeptId; //遍歷 foreach (var group in groupList) { Console.WriteLine(group.Key); foreach (var item in group) { Console.WriteLine(item.ToString()); } } Console.ReadKey(); } }
到此這篇關(guān)于C#的十種語法糖的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
VSCode調(diào)試C#程序及附缺失.dll文件的解決辦法
這篇文章主要介紹了VSCode調(diào)試C#程序及附缺失.dll文件的解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09C#事務(wù)處理(Execute Transaction)實例解析
這篇文章主要介紹了C#事務(wù)處理(Execute Transaction)實例解析,對于理解和學(xué)習(xí)事務(wù)處理有一定的幫助,需要的朋友可以參考下2014-08-08一看就懂:圖解C#中的值類型、引用類型、棧、堆、ref、out
這篇文章主要介紹了一看就懂:圖解C#中的值類型、引用類型、棧、堆、ref、out,本文用淺顯易懂的語言組織介紹了這些容易混淆的概念,需要的朋友可以參考下2015-06-06Unity實現(xiàn)物體沿自身的任意軸向旋轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了Unity實現(xiàn)物體沿自身的任意軸向旋轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-01-01C#配置log4net實現(xiàn)將日志分類記錄到不同的日志文件中
log4net是.Net下一個非常優(yōu)秀的開源日志記錄組件,log4net記錄日志的功能非常強(qiáng)大,它可以將日志分不同的等級,以不同的格式,輸出到不同的媒介,下面我們就來看看C#如何配置log4net讓日志分類記錄到不同的日志文件吧2024-02-02