標籤:自身 對象 log style 執行個體 匿名方法 cti 包含 ted
1、什麼是委託
從資料結構來講,委託是和類一樣是一種使用者自訂類型。
委託是方法的抽象,它儲存的就是一系列具有相同簽名和返回回類型的方法的地址。調用委託的時候,委託包含的所有方法將被執行。
2、委託的定義
委託是類型,就好像類是類型一樣。與類一樣,委託類型必須在被用來建立變數以及類型對象之前聲明。
委託的聲明原型是
delegate <函數傳回型別> <委託名> (<函數參數>)
例子:public delegate void MyDelegate(int number);//定義了一個委託MyDelegate,它可以註冊返回void類型且有一個int作為參數的函數
3、委託的執行個體化
3.1 使用new關鍵字
委託執行個體化的原型是
<委託類型> <執行個體化名>=new <委託類型>(<註冊函數>)
例子:MyDelegate _MyDelegate=new MyDelegate(CheckMod);//用函數CheckMod執行個體化上面的MyDelegate 委託為_MyDelegate
3.2 使用匿名方法
<委託類型> <執行個體化名>=delegate(<函數參數>){函數體};
3.3 使用Lambda運算式
1 class Program 2 { 3 //聲明委託 4 delegate int MyDelegate(int x, int y); 5 6 static void Main(string[] args) 7 { 8 //執行個體化委託 9 //1、使用new關鍵字10 MyDelegate _myDelegate = new MyDelegate(GetSum);11 12 //2、使用匿名方法13 MyDelegate myDelegate = delegate(int x, int y)14 {15 return x + y;16 };17 18 //3、使用Lambda運算式19 MyDelegate myDelegateLambda = (int x, int y) => { return x + y; };20 }21 22 static int GetSum(int x, int y)23 {24 return x + y;25 }26 }
4、泛型委派
委託也支援泛型的使用
泛型委派原型:
delegate <T1> <委託名><T1,T2,T3...> (T1 t1,T2 t2,T3 t3...)
例如:delegate T2 DelegateDemo<T1,T2>(T1 t);//定義有兩個泛型(T1,T2)的委託,T2作為委託函數傳回型別,T1作為委託函數參數類型
static boo Check(int i)
{
if(i%2==0)
{
return true;
}
return false;
}
static void Main(string[] args)
{
DelegateDemo<int, bool> _delegate =Check;//將泛型委派委託<T1,T2>執行個體化為<int,bool>,即表示有一個int型別參數且傳回型別是bool的函數.
Console.WriteLine(_delegate(9));//false
}
5、C#內建泛型委派
C#共有3種內建泛型委派
1 namespace DelegateDemo 2 { 3 class Program 4 { 5 //聲明委託 6 delegate int MyDelegate(int x, int y); 7 8 static void Main(string[] args) 9 {10 //1、Action<T>只能委託必須是無傳回值的方法11 Action<string> _action = new Action<string>(SayHello);12 _action("Hello World");13 14 //2、Fun<TResult>只是委託必須有傳回值的方法15 Func<int, bool> _func = new Func<int, bool>(Check);16 _func(5);17 18 //3、Predicate:此委託返回一個bool值,該委託通常引用一個"判斷條件函數"。19 //需要指出的是,判斷條件一般為“外部的硬性條件”,比如“大於50”,而不是由資料自身指定,如“尋找數組中最大的元素就不適合”。20 Predicate<int> _predicate = new Predicate<int>(Check);21 //使用Lambda運算式22 Predicate<int> predicate = p => p % 2 == 0;23 _predicate(26);24 }25 26 static void SayHello(string strMsg)27 {28 Console.WriteLine(strMsg);29 }30 31 //傳回值為bool值32 static bool Check(int i)33 {34 if (i % 2 == 0)35 {36 return true;37 }38 return false;39 } 40 }41 }
6、多播委託
執行個體化委託時必須將一個匹配函數註冊到委託上來執行個體化一個委派物件,但是一個執行個體化委託不僅可以註冊一個函數還可以註冊多個函數,註冊多個函數後,在執行委託的時候會根據註冊函數的註冊先後順序依次執行每一個註冊函數。
函數註冊委託的原型:
<委託類型> <執行個體化名>+=new <委託類型>(<註冊函數>)
例如:MyDelegate _myDelegate+=new MyDelegate(CheckMod);//將函數CheckMod註冊到委託執行個體_checkDelegate上
在.net 2.0開始可以直接將匹配的函數註冊到執行個體化委託:
<委託類型> <執行個體化名>+=<註冊函數>
例如:MyDelegate _myDelegate+=CheckMod;//將函數CheckMod註冊到委託執行個體_myDelegate上
注意:委託必須先執行個體化以後,才能使用+=註冊其他方法。如果對註冊了函數的委託執行個體從新使用=號賦值,相當於是重新執行個體化了委託,之前在上面註冊的函數和委託執行個體之間也不再產生任何關係。
有+=註冊函數到委託,也有-=解除註冊
例如:MyDelegate _myDelegate-=CheckMod;
如果在委託註冊了多個函數後,如果委託有傳回值,那麼調用委託時,返回的將是最後一個註冊函數的傳回值。
1 namespace DelegateDemo 2 { 3 class Program 4 { 5 //聲明委託 6 delegate int MyDelegate(int x, int y); 7 8 static void Main(string[] args) 9 {10 MyDelegate _myDelegate = new MyDelegate(fun1);11 _myDelegate += fun2;12 Console.WriteLine(_myDelegate(10,23));13 14 Console.ReadKey();//輸出10,返回最後一個註冊函數的傳回值15 }16 17 static int fun1(int x, int y)18 {19 return x + y;20 }21 22 static int fun2(int x, int y)23 {24 return x;25 } 26 }27 }
C#委託