1.委托的簡介:
委托可以簡單的理解為方法的列表,添加的方法的參數類型,個數,順序必須和委托一致,
也就是說委托起到了托管方法的作用,並且約束了要調用的方法.
1 //1聲明委托 2 public delegate void NoReturnNoPara(); 3 public delegate void NoReturnWithPara(string name, int id); 4 public delegate int WithReturnNoPara(); 5 public delegate string WithReturnWithPara(string name);
基礎代碼:



1 {
2 NoReturnWithPara method = new NoReturnWithPara(ShowPerson);//2 實例化委托
3 method.Invoke("盜墓者", 468);//3 委托調用
4 ShowPerson("盜墓者", 468);//方法的普通調用
5 }
2.匿名方法: 用delegate代替了方法名而已(修飾符和返回類型這裡看作方法名)
1 {
2 NoReturnWithPara method = new NoReturnWithPara(
3 delegate(string name, int id)
4 {
5 Console.WriteLine("this is id={0} name={1}", id, name);
6 });//匿名方法
7 method.Invoke("盜墓者", 468);
8 }
3.Lambda表達式
1 {
2 NoReturnWithPara method = new NoReturnWithPara(
3 (string name, int id) =>
4 {
5 Console.WriteLine("this is id={0} name={1}", id, name);
6 });//lambda表達式 把delegate換成箭頭
7 method.Invoke("盜墓者", 468);
8 //lambda表達式的本質就是一個匿名方法,,也就是一個方法
9 }
因為委托對方法有約束作用,所以,方法的參數類型可以省略
1 {
2 NoReturnWithPara method = new NoReturnWithPara(
3 (name, id) =>//lambda表達式方法主體只有一行,可以去掉大括號和分號
4 Console.WriteLine("this is id={0} name={1}", id, name)
5 );
6 method.Invoke("盜墓者", 468);
7 }
其他的形式:
1 {
2 NoReturnWithPara method = new NoReturnWithPara(
3 (name, id) =>//lambda表達式方法主體只有一行,可以去掉大括號和分號
4 Console.WriteLine("this is id={0} name={1}", id, name)
5 );
6 method.Invoke("盜墓者", 468);
7 }
{
//new一個委托的時候,可以簡寫
NoReturnWithPara method = (name, id) => Console.WriteLine("this is id={0} name={1}", id, name);//常用的形式
method.Invoke("盜墓者", 468);
}
4. Action 和 Func----這是系統自帶的委托,方便我們使用.
4.1-Action-無返回值的委托---看下面的in也看的出來啦!
先查看系統代碼的說明:



實例化:
1 //接受0到16個參數的 無返回值 泛型委托
2 Action act1 = () => Console.WriteLine("123"); //1
3 Action<string> act2 = t => { };//2
4 Action<Student, Class, int, long, Student, Class, int, long, Student, Class, int, long, Student, Class, int, long> act3 = null;//3
4.2. Func---有返回值---看out就看得出來啦!



不過,不管怎麼變,Func的最後一個始終都時out,因為它時有返回值的呗!

1 //接受0到16個參數的 帶返回值 泛型委托 2 Func<int> func1 = () => DateTime.Now.Millisecond;//4--返回int類型
//下面都返回string類型 3 Func<int,
string> func2 = t => DateTime.Now.Millisecond.ToString();//5 4 Func<Student, Class, int, long, Student, Class, int, long, Student, Class, int, long, Student, Class, int, long,
string> func3 = null;//6 5 //調用自己寫的,17個參數 6 Func<Student, Student, Class, int, long, Student, Class, int, long, Student, Class, int, long, Student, Class, int, long,
string> func4 = null;//6
5 擴展方法: 靜態類的靜態方法第一個參數加上 this.(靜態類不一定要加上static,只要有靜態方法的類就是靜態類)
1 /// <summary>
2 /// 靜態類的靜態方法,第一個參數前面加上this
3 /// </summary>
4 public static class ExtendTest
5 {
6 /// <summary>
7 /// 轉成int 失敗給0寫日志
8 /// </summary>
9 /// <param name="sNumber"></param>
10 /// <returns></returns>
11 public static int ToInt(this string sNumber)
12 {
13 int iNumber = 0;
14 if (int.TryParse(sNumber, out iNumber))
15 {
16 return iNumber;
17 }
18 else
19 {
20 Console.WriteLine("{0} 轉換失敗,給出默認值", sNumber);
21 return 0;
22 }
23 }
24
25 public static void Study(this Student student)
26 {
27 Console.WriteLine("1234");
28 }
29
30 public static void StudyVip(this Student student)
31 {
32 Console.WriteLine("1234");
33 }
34
35 public static void ConsoleShow(this object oValue)
36 {
37 Console.WriteLine(oValue);
38 }
39
40 }
調用: 就像給某個類添加了一個方法一樣,所以才叫擴展方法啊!
1 string sNumber = "123345";
2 ExtendTest.ToInt(sNumber);//普通調用--返回一個int
3 sNumber.ToInt();//擴展方法調用--返回一個int
4
5 Student student = new Student()
6 {
7 Name = "天道無情(387-天道無情-男)"
8 };
9 student.StudyVip();
10 student.Study();
11 student.ConsoleShow();
不過,擴展方法並非給this 修飾的類添加了一個方法,而是通過this添加了一個紐帶.
當我們調用擴展方法時,還是進入了我們自己寫的方法裡.
只不過它看起來像時我們給一個類注入了一個方法而已.(這裡用注入很形象的形容)
記住:擴展方法時寫在一個外部的靜態類裡,並且是一個靜態方法,參數類型前加this.
6. Linq 查詢

普通程序員一般會想的方法:
1 List<Student> studentList = GetStudentList();
2 {
3 List<Student> targetList = new List<Student>();
4 foreach (var item in studentList)
5 {
6 if (item.Age > 25)
7 {
8 targetList.Add(item);
9 }
10 }
11 }
Linq查詢和Lambda表達式查詢:

注:Where本身是一個擴展方法.
Lambda
1 {
2 Console.WriteLine("**************************");
3 var targetList = studentList.Where<Student>(t => t.Age > 25);//陳述式
4 foreach (var item in targetList)
5 {
6 Console.WriteLine(" {0} {1}", item.Age, item.Name);
7 }
8 Console.WriteLine("**************************");
9
Linq
1 Console.WriteLine("**************************");
2 var list = from s in studentList
3 where s.Age > 25
4 select s;
5 foreach (var item in list)
6 {
7 Console.WriteLine(" {0} {1}", item.Age, item.Name);
8 }
為了弄懂原理,請看下面:
7. Lambda查詢模擬器:
this IEnumerable<TSource> source 是數據源
Func<TSource, bool> predicate 是查找的方法,第一個參數是傳入參數in,後一個是返回類型-用於判斷.
1 public static class ElevenExtend
2 {
3 public static IEnumerable<TSource> ElevenWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
4 {
5 if (source == null) throw new Exception("null");
6
7 List<TSource> tList = new List<TSource>();
8
9 foreach (var item in source)
10 {
11 if (predicate.Invoke(item)) //調用時會返回一個bool
12 tList.Add(item);
13 }
14 return tList;
15 }
16 }
1 private static bool CheckStudentAge(Student student)
2 {
3 return student.Age > 25;
4 }
調用:
1 Func<Student, bool> func = new Func<Student, bool>(CheckStudentAge); //t => t.Age > 25; 2 var targetListEleven = studentList.ElevenWhere<Student>(func);//陳述式
foreach (var item in targetListEleven)
{
Console.WriteLine(" {0} {1}", item.Age, item.Name);
}
8. 其他的查詢:
1 {
2 Console.WriteLine("**************************");
3 var targetList =
studentList.Where<Student>(t => t.Age > 25 || t.Name.Contains("信仰") || new int[] { 1, 2 }.Contains(t.ClassId));//陳述式
4 foreach (var item in targetList)
5 {
6 Console.WriteLine(" {0} {1}", item.Age, item.Name);
7 }
8 }

1 {
2 var list = studentList.Select(s => new
3 {
4 IdAge = string.Format("{0}_{1}", s.Id, s.Age),
5 Name = s.Name
6 });
7 Console.WriteLine("**************************");
8 foreach (var student in list)
9 {
10 Console.WriteLine("Name={0} Age={1}", student.Name, student.IdAge);
11 }
12 }
對應的linq
1 {
2 var list = from student in studentList
3 //where student.Age > 25
4 select new
5 {
6 IdAge = string.Format("{0}_{1}", student.Id, student.Age),
7 Name = student.Name
8 };//語法糖
9
10 Console.WriteLine("**************************");
11 foreach (var student in list)
12 {
13 Console.WriteLine("Name={0} Age={1}", student.Name, student.IdAge);
14 }
15 }
1 {
2 Console.WriteLine("**************************");
3 foreach (var student in studentList.Where<Student>(s => s.ClassId == 2 && s.Id < 4)
4 .Select<Student, Student>(s =>
//Skip是跳過 Take是獲取
new Student { Age = s.Age, Name = string.Format("{0}_{1}", s.Name, s.Id) })
5 .OrderBy<Student, int>(s => s.Id)
6 .OrderByDescending<Student, int>(s => s.Age)
7 .Skip<Student>(1)//跳過1個
8 .Take<Student>(5))//獲取5個
9 {
10 Console.WriteLine("Name={0} Age={1}", student.Name, student.Age);
11 }
12 }
注:linq查詢編譯後還是調用的Lambda表達式.