C#中委託與事件的學習小結(一)
最近又學習了一些C#的小知識點,在此釋出部落格記錄一下。
一、委託
C#中的委託的關鍵字是delegate,我們可以使用委託型別來將已有的方法例項化出來,也可以將我們自己定義的方法作為引數來傳遞。
例如: private delegate string GetAString();//我們定義一個委託型別,這個委託的名字是GetAString
static void Main(string[] args) {
int x = 40;//定義了一個變數為x,為其賦值為40
GetAString a = new GetAString(x.ToString);//傳遞一個方法為引數,相當於a指向了x中的ToString方法。
//GetAString a = x.ToString;//第二種賦值方法,直接將方法賦值給委託變數。
string s = a();//通過委託的例項去呼叫x中的ToString方法。
Console.WriteLine(s);
Console.ReadKey();
}
上面這個例子中,存在兩種對委託型別變數a的賦值,第一種方法是直接改變a的指向,將ToString方法作為引數,傳遞給a,而第二種方法,則是直接將x中的方法賦值給a。這是已有方法ToString利用委託型別例項化出來的例子。下面分享一個自己定義方法作為引數進行委託傳遞的例子。
例:
private delegate void PrintString();//首先定義一個委託型別
static void PrintStr(PrintString print)//委託型別可以作為引數傳遞。 { print(); }
//定義的變數需要初始化才可以使用,所以新建立兩個方法,用來初始化method;
static void Method1() { Console.WriteLine("method1"); } static void Method2() { Console.WriteLine("method2"); }
static void Main(string[] args) {
PrintString method=Method1;//使用Method1方法來初始化method委託變數 PrintStr(method);//利用定義好的函式PrintStr來輸出method方法 method = Method2;//委託型別重新複製,呼叫引數改變,輸出結果也改變 PrintStr(method); Console.ReadKey();
}
大家可以注意到,我輸出了2次method委託變數,但是2次的結果是不同的,因為我們利用賦值的方式,在輸出Method1方法後將委託變數的值改變為Method2方法。而這個方法引數,正是我們一開始定義的PrintString委託型別的print方法。
二、Action委託和Func委託
下面說一下C#語言中為我們定義好的兩個委託型別:
1、Action委託
這個委託最大的特點是它只能指定沒有返回值的方法,也就是void型別的方法,而他傳遞的方法中可以包含0個或多個引數。也就是說,既沒有引數也沒有返回值的方法也可以通過Action委託進行傳遞。
例: static void PrintDoubleInt(int i1, int i2)//我們先定義一個方法,注意它沒有返回值 { Console.WriteLine(i1+i2); }
static void Main(string[] args) {
Action<int , int> a=PrintDoubleInt;//我們將方法中的2個引數利用泛型<>來傳遞。
a(23,33);//然後我們隨意在委託變數a中傳遞兩個引數。
Console.ReadKey();
}
這裡要注意,Action後面泛型中的型別,一定要與宣告此方法中的引數一一對應。然後輸出結果為兩個int引數的和。
2、Func委託
這個委託跟Action委託正好對應,他是必須要有返回值的委託型別。引數方面與Action委託要求基本一致,可以有0個或多個引數,但是方法的返回值型別不能為空。
例: static int Test3(int i, int j) { return i + j; }
static void Main(string[] args) { Func<int, int, int> a = Test3;//func後面必須指定一個返回值型別,引數型別可以有0-16個, //先寫引數型別,最後一個是返回值型別。 int res = a(1, 5); Console.WriteLine(res); Console.ReadKey(); }
通過例子我們可以發現Func後面可以跟很多型別,最後一個是返回值型別,前面的型別是引數型別,引數型別必須跟指向的方法的引數型別按照順序對應。
三、多播委託
下面跟大家說一下什麼是多播委託。多播委託就是一個將各個委託集合到一起,做成一個Delegate[],然後我們同樣可以通過foreach的方法,對其內部的委託進行查詢。那麼我們如何將各種方法集合到一起呢?下面寫個小例子,大家就明白了。
例://常規建立兩個測試方法:
static void Test1() { Console.WriteLine("test1"); }
static void Test2() { Console.WriteLine("test2"); }
static void Main(string[] args) { Action a = Test1;//將Test1賦值給委託a;
a += Test2;//通過+=符號,為委託變數增加Test2方法;
a();
Console.ReadKey();
}
我們可以通過+=和-=這兩個符號,對委託型別a中的方法集合進行增減,但是要注意,如果這個委託集合中有任何一個方法發生異常的話,整個集合的迭代都會停止。