首頁 > 軟體

C#的十種語法糖介紹

2022-02-24 16:00:32

語法糖

指計算機語言中新增的某種語法,這種語法對語言的功能並沒有影響,但是更方便程式設計師使用。通常來說使用語法糖能夠增加程式的可讀性,從而減少程式程式碼出錯的機會。

需要宣告的是“語法糖”這個詞絕非貶義詞,它可以給我們帶來方便,是一種便捷的寫法,編譯器會幫我們做轉換,而且可以提高開發編碼的效率,在效能上也不會帶來損失。

一、自動屬性

以前:手寫私有變數+公有屬性
現在:宣告空屬性,編譯器自動生成對應私有成員欄位。

寫法:輸入prop ,連續按兩次tab鍵,自動生成屬性。

        /// <summary>
        /// 自動屬性
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 傳統屬性寫法
        /// </summary>
        private string _LoginName;

        public string LoginName
        {
            get { return _LoginName; }
            set { _LoginName = value; }
        }

 二、隱式型別(var)

var定義變數有以下四個特點:

程式設計師在宣告變數時可以不指定型別,由編譯器根據值來指定型別

  • 1、必須在定義時初始化
  • 2、一旦初始化完成,就不能再給變數賦與初始值不同型別的值了
  • 3、var要求是區域性變數
  • 4、使用var定義變數和object不同,它在效率上和使用強型別方式定義變數完全一樣

注意:
a.隱式型別在定義時必須初始化
例如:var name; 錯  var name="Tom";正確
b.可以用同型別的其他隱式型別變數來初始化新的隱式型別變數
例如:var v=1;
      var v2=v;
c.也可以用同型別的字面量來初始化隱式型別變數
例如: var v3="hello";
      v3="world";
d.隱式型別區域性變數還可以初始化陣列而不指定型別
例如: var array=new int[]{1,2,3,4,5}; (注意:賦值運運算元左邊沒有方括號)
e.編譯器可以根據變數的初始值“推斷”變數的型別
例如: var number=0;  編譯後就變成了  int number =0;

三、引數預設值和命名引數

C#方法的可選引數是.net 4.0最新提出的新的功能,對應簡單的過載可以使用可選引數和命名引數混合的形式來定義方法,這樣就可以很高效的提高程式碼的執行效率

設計一個方法的引數時,可以部分或全部引數分配預設值。呼叫其方法時,可以重新指定分配了預設值的引數,也可以使用預設值。重新指定分配預設值的引數時,可以顯式地為指定引數名稱賦值;隱式指定的時候,是根據方法引數的順序,靠C#編譯器的推斷。

使用的指導原則:

  • 1、可以為方法和有參屬性指定預設值
  • 2、有預設值的引數,必須定義在沒有預設值的引數之後
  • 3、預設引數必須是常數
  • 4、ref和out引數不能指定預設值
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; }

        //建構函式過載
        public User(string name)
        {
            this.Name = name;
        }

        public User(string name,string loginName)
        {
            this.Name = name;
            this.LoginName = loginName;
        }

        /// <summary>
        /// 預設引數
        /// </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;
        }
    }

使用預設值引數和命名引數
 class Program
    {
        static void Main(string[] args)
        {
            //引數預設值:可以給引數賦值也可以使用引數預設值
            //1、使用預設值
            User user = new User("小明","xiaoming",27);
            Console.WriteLine(user.Address);//輸出預設值:上海

            //2、給引數賦值
            User user2 = new User("小紅", "xiaohong", 28,"北京");
            Console.WriteLine(user2.Address);//輸出:北京

            //命名引數:使用預設值引數的時候,指定引數的名稱,命名引數要寫在所有固定引數的後面
            //好處:適用於有多個預設值引數的情況,根據命名引數,只修改需要修改的預設值
            //使用命名引數只修改密碼
            User user3 = new User("小紅", "xiaohong", 28,password:"5678");
            Console.WriteLine(user3.Password);//輸出:5678

            Console.ReadKey();
        }
    }

輸出結果:

四、物件初始化器和集合初始化器

class Program
    {
        static void Main(string[] args)
        {

            //傳統的初始化物件的方式
            User zjl = new User();
            zjl.Name = "周杰倫";
            zjl.phone = "12345678956";

            //使用物件初始化器:{},使用物件初始化器,必須提供一個無參的建構函式,可以只給部分屬性初始化
            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();
        }
    }

五、匿名類和匿名方法

匿名型別

有時候你定義的類只是用來封裝一些相關的資料,但並不需要相關聯的方法、事件和其他自定義的功能。同時,這個類僅僅在當前的應用程式中使用,而不需要在專案間重用。你所需要的只是一個“臨時的”型別,現在來看看這個類的定義

internal class oneClass
{
   //定義若干私有資料成員
   //通過屬性來封裝每個資料成員
}

構建上面的類雖然說不上有多難,但是如果這個類有很多資料成員的話,那麼還是要消耗相當時間的。C#3.0提供了匿名型別來輕鬆完成這個工作。
現在定義一個匿名物件來表示一個人
var aPeople=new {pName="張三",pAge=26,pSex="男"};
現在我們就可以使用屬性語法獲取和設定物件的各個變數

aPeople.pAge=29;
Console.WriteLine("{0} is {1}years old",aPeople.pName,aPeople.pAge);

匿名型別的巢狀

剛剛我們定義了表示一個人的匿名型別,現在我們定義一個表示僱員的巢狀匿名型別:

    var Aemployee=new {
        JoinDate="2012-09-23",
        aPeople=new {pName="張三",pAge=26,pSex="男"},
        title=Manager
    };

匿名型別的限制:

  • 1、匿名型別不支援事件、自定義方法和自定義重寫
  • 2、匿名型別是隱式封閉的
  • 3、匿名型別的範例建立只使用預設建構函式
  • 4、匿名型別沒有提供可供控制的類名稱(使用var定義的)

匿名方法

普通方法定義方式,因為方法的存在是為了複用一段程式碼,所以一般會給方法取個名字,這個方法的參照就可以通過“方法名”呼叫

匿名方法:

但是有的方法,不需要複用,僅僅是使用一次就夠了,所以不需要方法名,這種方法就叫做匿名方法。

匿名方法必須結合委託使用。(潛在的意思就是:儘管沒有方法名了,但方法的指標還是存放了某個委託物件中)

注意:

  • 1、在編譯後,會為每個匿名方法建立一個私有的靜態方法,然後將此靜態方法傳給委託物件使用
  • 2、匿名方法編譯後會生成委託物件,生成方法,然後把方法裝入委託物件,最後賦值給宣告的委託變數
  • 3、匿名方法可以省略引數,編譯的時候會自動為這個方法按照委託簽名的引數新增引數
public class Test
    {
        public static void TestFive()
        {
            //匿名型別:只能使用一次,僅能在當前的專案中使用
            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)
        {
            //匿名方法:必須結合委託使用
            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表示式
            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);
            }
        }
    }

六、擴充套件方法

為什麼要有擴充套件方法,就是為了在不修改原始碼的情況下,為某個類增加新的方法。

語法:

定義靜態類,並新增public的靜態方法,第一個引數代表擴充套件方法的擴充套件類。它必須放在一個非巢狀、非泛型的靜態類中(的靜態方法);它至少有一個引數;第一個引數必須附加this關鍵字;第一個引數不能有任何其他修飾符(out/ref).第一個引數不能是指標型別。

注意:

  • 1、C#只支援擴充套件方法,不支援擴充套件屬性、擴充套件事件等;
  • 2、方法名無限制,第一個引數必須帶this,表示要擴充套件的型別;
  • 3、擴充套件方法的名稱空間可以使用namespace System,但不推薦;
  • 4、定義擴充套件方法的類必須是靜態類;
  • 5、擴充套件方法雖然是public的靜態方法,但是生成以後是實體方法,使用時需要先範例化物件,通過物件.方法名進行呼叫擴充套件方法;
/// <summary>
    /// 靜態類:對Convert進行擴充套件,增加一個將string轉換成int的方法
    /// </summary>
    public static class ConvertExtension
    {
        /// <summary>
        /// 靜態方法:this 表示針對this後面的型別進行擴充套件
        /// </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)
        {
            //使用擴充套件方法:擴充套件方法雖然是public的靜態方法,但是生成以後是實體方法,使用時需要先範例化物件,通過物件.方法名進行呼叫擴充套件方法
            //擴充套件方法所在名稱空間和使用程式碼的名稱空間必須相同 擴充套件方法必須是靜態類
            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();
        }
    }

七、內建泛型委託

Action<T>
可以使用Action<T>委託以引數形式傳遞方法,而不用顯示宣告自定義的委託。封裝的方法必須與此委託定義的方法簽名相對應,也就是說,封裝的方法必須具有一個通過值傳遞給它的引數,並且不能有返回值。
通常,這種方法用於執行某個操作。

/// <summary>
    /// List擴充套件方法
    /// </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="財務部",PepNum=7},
                  new Dept(){DeptId="0003",DeptName="行政部",PepNum=15}
            };


            #region 使用自定義委託

            //列印所有使用者資訊
            listUser.TEach(PrintUser);

            listDept.TEach(PrintDept);

            #endregion


            #region 使用內建泛型委託

            listUser.ForEach(PrintUser);
            //使用匿名方法
            listUser.ForEach(delegate(User u) { Console.WriteLine(u.Name + " " + u.Password + " " + u.phone); });

            //使用Lambda表示式
            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="財務部",PepNum=7},
                  new Dept(){DeptId="0003",DeptName="行政部",PepNum=15}
            };

            //使用內建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="財務部",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));

            //根據使用者資訊得到員工資訊
            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表示式

Lambda表示式是比匿名方法更簡潔的一種匿名方法語法

最基本的Lambda表示式語法:
{參數列}=>{方法體}
例如:
(int x)=>{returm x+1}
說明:
1、參數列中的引數型別可以是明確型別或推斷型別
2、如果是推斷型別,則引數的資料型別將由編譯器根據上下文自動推斷出來

如果參數列只包含一個推斷型別引數時:
參數列=>{方法體}
前提:x的資料型別可以根據上下文推斷出來
 x =>{returm x+1}

如果方法體只包含一條語句時:
{參數列}=>表示式
{int x} => x+1;

Lambda表示式範例:
1、多引數,推斷型別參數列,表示式方法體
(x,y) => x*y
2、無引數,表示式方法體
() => Console.WriteLine()
3、多引數,推斷型別參數列,多語句方法體,需要使用{}
(x,y) => {Console.WriteLine(x);Console.WriteLine(y)}

Lambda表示式縮寫推演
new Func<string,int>(delegate(string str){return str.Length;});//內建委託
delegate(string str){return str.Length;}//匿名方法
(string str)=>{return str.Length};//Lambda表示式
(str)=>str.Length;//讓編譯器推斷型別
str=>str>Length;//去掉不必要的括弧

#region Lambda表示式

            //標準語法
            MyDelegate my1 = (string name) => { return "Lambda表示式:hello" + name; };
            Console.WriteLine(my1("tom"));

            //或者(僅有一個引數) 參數列只包含一個推斷型別引數
            MyDelegate my2 = name => { return "Lambda表示式:hello" + name; };
            Console.WriteLine(my2("tom"));

            //或者(方法體只有一條語句)
            MyDelegate my3 = name => "Lambda表示式:hello" + name;
            Console.WriteLine(my3("tom"));

            #endregion

九、標準查詢運運算元

標準查詢運運算元:定義在System.Linq.Enumerable類中的50多個為IEnumerable<T>準備的擴充套件方法,這些方法用來對它操作的集合進行查詢篩選。
篩選集合where:需要提供一個帶bool返回值的“篩選器”,從而標明集合中某個元素是否應該被返回。
查詢投射:返回新物件集合IEnumerable<TSource> Select()
統計數量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="財務部",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();
            //迴圈輸出
            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();
            //迴圈輸出
            udVar.ForEach(p => Console.WriteLine(p.UserName));

            #region 4.0 group by 分組

            //4.1 按照集合中的使用者的部門編號進行分組
            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:取

            //分頁前提:資料來源按照一定的列進行排序
            List<User> listSource = listUser.OrderBy(p => p.Name).ToList();
            foreach (User user in listSource)
            {
                Console.WriteLine(user.Name);
            }

            Console.WriteLine("--------------");
            //取第一頁資料,每頁顯示2條資料
            List<User> list = GetPageListByIndex(listUser, 1, 2);
            //輸出分頁結果
            foreach (User user in list)
            {
                Console.WriteLine(user.Name);
            }

            #endregion

            Console.ReadKey();
        }

        /// <summary>
        /// 根據頁碼提取當頁資料
        /// </summary>
        /// <param name="listSource">要分頁的資料</param>
        /// <param name="pageIndex">頁碼</param>
        /// <param name="pageSize">每頁要顯示的條數</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,使得你可以使用統一的方式編寫各種查詢。查詢的物件包括XML、物件集合、SQL Server資料庫等等。
Linq to Objects:主要負責物件的查詢
Linq to XML:主要負責XML的查詢
Linq to ADO.NET:主要負責資料庫的查詢
  Linq to SQL
  Linq to DataSet
  Linq to Entities

Linq查詢的兩種方式:
1、查詢方法方式:主要利用System.Linq.Enumerable類中定義的擴充套件方法和Lambda表示式進行查詢
2、查詢語句方式:一種更接近SQL語法的查詢方式

查詢語句VS查詢方法
1、CLR本身並不理解查詢語句,它只理解查詢方法
2、編譯器負責在編譯時將查詢語句翻譯成查詢方法
3、大部分查詢方法都有對應的查詢語句形式:Select()對應select、OrderBy()對應orderby
4、部分查詢方法目前在C#中還沒有對應的查詢語句,如:Count()和Max()這時只能採用以下替代方案:
   查詢方法
   查詢語句+查詢方法的混合方式

class Program
    {
        //宣告委託
        public delegate string MyDelegate(string name);

        static void Main(string[] args)
        {
            //建立int型別陣列,查詢其中的偶數並降序排序輸出
            int[] arrays = { 5, 2, 0, 66, 4, 32, 7, 1 };

            #region  使用迴圈實現

            List<int> list = new List<int>();
            foreach (int i in arrays)
            {
                if (i % 2 == 0)
                {
                    list.Add(i);
                }
            }
            //排序
            list.Sort();
            //反轉
            list.Reverse();

            Console.WriteLine(string.Join(",", list));


            #endregion

            #region 使用Linq實現
            //查詢方法方式
            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 擴充套件方法
            //擴充套件方法 擴充套件方法所在名稱空間和使用程式碼的名稱空間必須相同 擴充套件方法必須是靜態類
            string s = "abc";
            int a = s.ToInt();//方法圖示有一個向下的箭頭,表示是擴充套件方法
            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
            //呼叫委託
            string strName = my("tom");
            Console.WriteLine(strName);


            #region 匿名方法(只用一次)
            MyDelegate my2 = delegate(string str)
            {
                return "匿名方法:hello" + str;
            };

            //呼叫
            string name= my2("tom");
            Console.WriteLine(name);
            #endregion

            #region Lambda表示式

            //標準語法
            MyDelegate my1 = (string str) => { return "Lambda表示式:hello" + str; };
            Console.WriteLine(my1("tom"));

            //或者(僅有一個引數) 參數列只包含一個推斷型別引數
            MyDelegate myDel = p => { return "Lambda表示式:hello" + p; };
            Console.WriteLine(my2("tom"));

            //或者(方法體只有一條語句)
            MyDelegate my3 = p => "Lambda表示式:hello" + p;
            Console.WriteLine(my3("tom"));

            #endregion

            //Linq
            //兩種查詢方式
            //Select
            int[] intArray = { 1,2,3,6,4,90,65,44,9};

            //1、查詢方法方式 p:指的是intArray陣列中的每一個元素
            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);//選擇陣列中的偶數
            //查詢語句(一般以select結尾)
            var3 = from number in intArray
                   where number % 2 == 0
                   select number;

            //多個條件(刷選出陣列中大於10的偶數)
            //查詢方法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=""的聯絡人的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);
            }

            //刪除重複元素,沒有對應的查詢語句
            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);
            //級聯呼叫
            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));

            //複雜查詢
            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="財務部",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();
        }
    }

 到此這篇關於C#的十種語法糖的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com