前言:Action與Func是.NET類庫中增加的內置委託,以便更加簡潔方便的使用委託。在前面的博文中,我介紹了C#委託(Delegate),那麼本博文,主要是介紹Action與Func,算是對之前博文的一個補充與擴展。參考博文:C#委託(Delegate)精講
一、關於委託補充
委託是引用類型,可以把它看作是用來存方法的一種類型。比如說類型string用來定義存取字符串的變量,那麼委託類型delegate就可以用來定義存方法的變量。委託和類一樣,是一種用戶自定義類型。但類表示的是數據和方法的集合,而委託表示的是一個或多個方法的集合。你可以把delegate看作一個包含有序方法列表的對象,這些方法具有相同的簽名和返回類型。
-
方法的列表稱爲調用列表。
-
委託保存的方法可以來自任何類和結構,只要它們在下面兩點匹配:
- 委託的返回類型
- 委託的簽名(包括ref和out修飾符)
-
調用列表中的方法可以是實例方法,也可以是靜態方法
-
在調用委託的時候,會執行其調用列表中的所有方法
除了我們自己定義的委託之外,系統還爲我們提供過來一個內置的委託類型,Action與Func。其中Action委託引用了一個void返回類型的方法。Func引用了一個帶有一個返回值的方法,它可以傳遞0或者多到16個參數類型,和一個返回類型。
二、Action委託
Action委託簽名不提供返回類型,它具有Action、Action<T1,T2>、Action<T1,T2,T3>……Action<T1,……T16>多達16個的重載,其中傳入參數均採用泛型中的類型參數T,涵蓋了幾乎所有可能存在的無返回值的委託類型。
例如:
private static void Print()
{
Console.WriteLine("我是一個普通的輸出方法");
}
private static void Add(int a,int b)
{
Console.WriteLine("a+b的值爲{0}",a+b);
}
private static void Adds(string name,int age)
{
Console.WriteLine("我的名字叫:{0},今年{1}歲",name,age);
}
public static void Main(string[] args)
{
Action ac1 = Print; // Action是系統內置(預定義)的一個委託類型,它可以指向一個沒有返回值,沒有參數的方法
ac1();
Action<int, int> ac2 = Add; // 定義了一個委託類型,這個類型可以指向一個沒有返回值,有兩個int參數的方法
ac2(3, 4);
Action<string, int> ac3 = Adds; // Action可以後面通過泛型去指定Action指向的方法的多個參數的類型,參數的類型跟Action後面聲明的委託類型是對應的
ac3("張三", 23);
}
執行效果:
三、Func委託
Func具有Func<TResult>、Func<T,Tresult>、Func<T1,T2,T3……,Tresult>17種類型重載,T1……T16爲出入參數,Tresult爲返回類型。
例如:
private static int Test()
{
return 1;
}
private static int Mes(string name)
{
Console.WriteLine("我的名字叫:"+name);
return 100;
}
private static int Add(int a, int b)
{
return a + b;
}
public static void Main(string[] args)
{
Func<int> fu1 = Test; // Func中的泛型類型指定的是方法的返回值類型
int res1 = fu1();
Console.WriteLine(res1);
Func<string,int> fu2 = Mes; // Func後面可以跟很多類型,最後一個類型是返回值類型,前面的類型是參數類型,參數類型必須跟指向的方法的參數類型安裝順序對應
int res2 = fu2("李四");
Console.WriteLine(res2);
Func<int,int,int> fu3 = Add; // Func後面必須指定一個返回值類型,參數類型可以有0~16個,先寫參數類型,最後一個是返回值類型
int res3 = fu3(2,3);
Console.WriteLine(res3);
}
執行效果:
四、Predicate委託
- Predicate是返回bool型的泛型委託
- Predicate<int>表示傳入參數爲int,返回bool的委託
- Predicate有且只有一個參數,返回值固定爲bool
例如:
private static bool isEqual(bool b)
{
return b;
}
public static void Main(string[] args)
{
Predicate<bool> pre = isEqual; // Predicate是返回bool型的泛型委託,故泛型裏只能是bool,它有且只有一個參數
bool res = pre(2>1);
Console.WriteLine(res);
}
執行效果:
五、委託特點與異同
1、特點
- 委託類似於C++函數指針,但它們是類型安全的。
- 委託允許將方法作爲參數進行傳遞。
- 委託可用於定義回調方法。
- 委託可以鏈接在一起;例如,可以對一個事件調用多個方法。
- 方法不必與委託簽名完全匹配。
2、異同
- Delegate至少0個參數,至多32個參數,可以無返回值,也可以指定返回值類型。
- Func可以接受0個至16個傳入參數,必須具有返回值。
- Action可以接受0個至16個傳入參數,無返回值。
- Predicate只能接受一個傳入參數,返回值爲bool類型。