[C#基礎]Func和Action學習
委托
委托的那些事
關於委托的基本定義,在很久之前的這篇文章中,有個簡單的介紹。稍微回顧一下。
委托是c#中類型安全的,可以訂閱一個或多個具有相同簽名方法的函數指針
聲明委托的方式:delegate 返回值類型 委托類型名(參數)
例如:
1 delegate void Say(string strContent);
如果想使用該委托,需要一個對應的方法。
復制代碼
1 /// <summary>
2 /// 委托對應方法
3 /// </summary>
4 /// <param name="strContent"></param>
5 private static void ChineseSay(string strContent)
6 {
7 Console.WriteLine(strContent);
8 }
復制代碼
簡單的調用:
復制代碼
1 static void Main(string[] args)
2 {
3 Say sy = new Say(ChineseSay);//方式一
4 Say say = ChineseSay;//方式二
5 sy("您好");
6 say("您好");
7 Console.Read();
8 }
復制代碼
上面介紹了,平時用委托的一般方式,先聲明委托,然後再去使用,有點麻煩,.net中有已經定義好的委托類型,可以拿來直接用。
Action
Action委托有兩種方式:無參數無返回值的委托,有至少一個最多16個的參數無返回值的泛型委托。
1 // 摘要:
2 // 封裝一個方法,該方法不具有參數並且不返回值。
3 [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
4 public delegate void Action();
Action泛型委托根據輸入參數個數的不同,Action委托有十六個重載
用Action改寫上面的例子,上面的例子中委托是無返回值有string類型的輸入參數,所以使用Action的泛型版本。
復制代碼
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 Action<string> SayHello = new Action<string>(ChineseSay);//方式一
6 Action<string> SayName = ChineseSay;//方式二
7 Action<string> SayAge = s => Console.WriteLine("我今年{0}歲了", s);//方式三
8 SayHello("您好");
9 SayName.Invoke("我叫Wolfy");
10 IAsyncResult result = SayAge.BeginInvoke("27", CallBack, "愛好女");
11 if (result.IsCompleted)
12 {
13 SayAge.EndInvoke(result);
14 }
15 Console.Read();
16 }
17
18 private static void CallBack(IAsyncResult ar)
19 {
20 Console.WriteLine("介紹完畢,忘了,我{0},我不搞基",ar.AsyncState.ToString());
21 }
22 /// <summary>
23 /// 委托對應方法
24 /// </summary>
25 /// <param name="strContent"></param>
26 private static void ChineseSay(string strContent)
27 {
28 Console.WriteLine(strContent);
29 }
30 }
上面代碼中,列出了Action泛型委托的使用方式,以及使用Lambda的方式,Action也可以使用匿名方法,選擇一種自己上手的來用即可。
Func
如果要用有輸入參數,有返回值的委托,那麼Func委托將滿足你的要求。
Func泛型委托,可以沒有輸入參數,但必須有返回值。根據輸入參數的多少有17個重載。
in:輸入參數
out:輸出參數,也就是返回值。
一個案例
輸入名字,年齡,性別,對年齡,性別,姓名進行修改後輸出。
復制代碼
1 public class Person
2 {
3 public string Name { set; get; }
4 public int Age { set; get; }
5 public bool Gender { set; get; }
6 /// <summary>
7 /// 重寫tostring方法,方便輸出結果
8 /// </summary>
9 /// <returns></returns>
10 public override string ToString()
11 {
12 return Name + "\t" + Age + "\t" + Gender;
13 }
14 }
15 class Program
16 {
17 static void Main(string[] args)
18 {
19 Func<Person, Person> funcUpdateAge = new Func<Person, Person>(UpdateAge);
20 Func<Person, Person> funcUpdateAge2 = UpdateAge;
21 Func<Person, Person> funcUpdateGender = (p1) => { p1.Gender = false; return p1; };//lambda表達式方式
22 Func<Person, Person> funUpdateName = delegate(Person p2)//匿名方法
23 {
24 p2.Name = "Wolfy2";
25 return p2;
26 };
27 Person p = new Person() { Name = "Wolfy", Age = 24, Gender = true };
28 Person result = funcUpdateAge(p);
29 Console.WriteLine(result.ToString());
30 Console.WriteLine(funcUpdateGender(p).ToString());
31 Console.WriteLine(funUpdateName(p).ToString());
32 Console.Read();
33 }
34 static Person UpdateAge(Person p)
35 {
36 p.Age = 25;
37 return p;
38 }
39
40 }
Func泛型委托,可以沒有輸入參數,但是必須有輸出參數。
總結
Action:無參數無返回值委托。
Action<T>:泛型委托,無返回值,根據輸入參數的個數不同有十六個重載。
Func< out T>:無輸入參數,有返回值。
Func<in T,out T>:有輸入參數,有返回值,根據輸入參數個數不同,有十六個重載。
Action和Func中可以使用Lambda和匿名方法處理方法體內邏輯。
(天太熱,人很躁,在你不知道做什麼的時候,不如靜下來對基礎進行查漏補缺,能掌握一點是一點,別總抱怨,總煩躁,就算你抱怨,煩躁,最後該完成的事還是你的,不多不減就在那裡,夏天這天氣,太煩躁,啥事都不做了嗎?難道敲代碼不是一件開心的事嗎?)