C# 委托簡介(delegate、Action、Func、predicate)

委托是一種定義方法簽名的類型。當(dāng)實(shí)例化委托時(shí),您可以將其實(shí)例與任何具有兼容簽名的方法相關(guān)聯(lián)。您可以通過委托實(shí)例調(diào)用方法。

如何使用委托?

1、定義委托類型

[訪問修飾符] ?delegate ?返回類型 ?委托名(形參);

2、聲明委托對象

委托名 委托實(shí)例名;

3、創(chuàng)建委托對象

委托實(shí)例名 = new 委托名(某個(gè)類的方法)

4、使用委托調(diào)用方法

委托實(shí)例名(實(shí)參)

委托注意事項(xiàng):

1、委托和方法必須具有相同的簽名。

2、委托可以調(diào)用多個(gè)方法,即一個(gè)委托對象可以維護(hù)一個(gè)可調(diào)用方法的列表而不是單獨(dú)的一個(gè)方法,稱為多路廣播(多播)。

3、使用+=和-=運(yùn)算實(shí)現(xiàn)方法的注冊和注銷

寫法:

1、委托 ?委托名 ?= ?new ?委托(會調(diào)用的方法名);

? ?? 委托名(參數(shù));

? ??CallobjCall =newCall(SimpleMath.Multiply);

? ?CallobjCall1 =newCall(newSimpleMath().Divide);

2、委托 ?委托名 ?= ?會調(diào)用的方法名;

? ?? 委托名(參數(shù));

? ?CallobjCall =SimpleMath.Multiply;

? ?CallobjCall1 =newSimpleMath().Divide;

3、匿名方法

? ? ? 委托 ?委托名 ?= ?delegate(參數(shù)){會調(diào)用的方法體};

? ? ? 委托名(參數(shù));

? ? ?CallobjCall ?=delegate(inta,intb) {?return?a * b;?};

? ? ?CallobjCall1 =delegate(inta,intb) {?returna / b;?};

4、lambda表達(dá)式

? ? ? 委托 ?委托名 = ((參數(shù)1,。。參數(shù)n)=>{會調(diào)用的方法體});

? ? ? 委托名(參數(shù));

? ??CallobjCall = ((inta,intb) => {returna * b; });

? ??CallobjCall1 = ((inta,intb) => {returna / b; });

5、用Action和Func,第一個(gè)無返回值

? ? ?Func<參數(shù)1, 參數(shù)2, 返回值> 委托名 = ((參數(shù)1,參數(shù)2) => {帶返回值的方法體 });

? ? ?返回值 = 委托名(參數(shù)1,參數(shù)2);

? ??Action obj = ((a, b) => {Console.WriteLine(a * b); });

? ?? obj(5, 3);

? ? ?Func objCall = ((a, b) => {returna * b; });

? ??intresult = objCall(5, 3);

? ??Func objCall1 = ((a, b) => {returna / b; });

? ??intresult1 = objCall1(5, 3);

1.委托的聲明

 ?(1). delegate

? ?? ? ?delegate是我們常用到的一種聲明。

   Delegate至少0個(gè)參數(shù),至多32個(gè)參數(shù),可以無返回值,也可以指定返回值類型。

   例:public?delegate?int?MethodtDelegate(int?x,?int?y);表示有兩個(gè)參數(shù),并返回int型。

?(2). Action

? ? ? ? Action是無返回值的泛型委托。

   Action表示無參,無返回值的委托。

   Action 表示有傳入?yún)?shù)int,string無返回值的委托。

?  Action 表示有傳入?yún)?shù)int,string,bool無返回值的委托。

? ? ? ? Action 表示有傳入4個(gè)int型參數(shù),無返回值的委托。

  ? Action至少0個(gè)參數(shù),至多16個(gè)參數(shù),無返回值。

   例:

? ? ? ? public void Test(Action action,T p)

? ? ? ? {

? ? ? ? ? ? ?action(p);

? ? ? ? }

??(3). Func

   Func是有返回值的泛型委托

   Func 表示無參,返回值為int的委托

   Func 表示傳入?yún)?shù)為object,string 返回值為int的委托

   Func 表示傳入?yún)?shù)為T1,T2,T3(泛型)返回值為int的委托

   Func至少0個(gè)參數(shù),至多16個(gè)參數(shù),根據(jù)返回值泛型返回。必須有返回值,不可void

? ? ? ? 例:

? ? ? ? public int Test(Funcfunc,T1 a,T2 b)

? ? ? ? {

? ? ? ? ? ? ?return func(a, b);

? ? ? ? }

? ?(4) .predicate

   predicate是返回bool型的泛型委托

   predicate 表示傳入?yún)?shù)為int 返回bool的委托

   Predicate有且只有一個(gè)參數(shù),返回值固定為bool

   例:public?delegate?bool?Predicate (T obj)

2.委托的使用

(1).Delegate的使用

? ? ? ? public delegate int MethodDelegate(int x, int y);

? ? ? ? private static MethodDelegate method;

? ? ? ? static void Main(string[] args)

? ? ? ? {

? ? ? ? ? ? method = new MethodDelegate(Add);

? ? ? ? ? ? Console.WriteLine(method(10,20));

? ? ? ? ? ? Console.ReadKey();

? ? ? ? }

? ? ? ? private static int Add(int x, int y)

? ? ? ? {

? ? ? ? ? ? return x + y;

? ? ? ? }

  (2).Action的使用

? ? ? ? static void Main(string[] args)

? ? ? ? {

? ? ? ? ? ? Test(Run,"Hello World!");

? ? ? ? ? ? Test(Run, 1000);

? ? ? ? ? ? //使用Lambda表達(dá)式定義委托 ? ? ?

? ? ? ? ? ? Test(p => { Console.WriteLine("{0}", p); }, "Hello World"); ? ??

? ? ? ? ? ? Console.ReadKey();

? ? ? ? }

? ? ? ? public static void Test(Action action, T p)

? ? ? ? {

? ? ? ? ? ? action(p);

? ? ? ? }

? ? ? ? private static void Run(string s)

? ? ? ? {

? ? ? ? ? ? Console.WriteLine(s);

? ? ? ? }

? ? ? ? private static void Run(int s)

? ? ? ? {

? ? ? ? ? ? Console.WriteLine(s);

? ? ? ? }

 ? ?可以使用 Action 委托以參數(shù)形式傳遞方法,而不用顯式聲明自定義的委托。

? ? ? 封裝的方法必須與此委托定義的方法簽名相對應(yīng)。?也就是說,封裝的方法必須具有四個(gè)均通過值傳遞給它的參數(shù),并且不能返回值。

(3).Func的使用

? ? ? ? static void Main(string[] args)

? ? ? ? {

? ? ? ? ? ? Console.WriteLine(Test(Run,100,200));

? ? ? ? ? ? Console.ReadKey();

? ? ? ? }

? ? ? ? public static int Test(Func func, T1 a, T2 b)

? ? ? ? {

? ? ? ? ? ? return func(a, b);

? ? ? ? }

? ? ? ? private static int Run(int a, int b)

? ? ? ? {

? ? ? ? ? ? return a + b;

? ? ? ? }

 (4).?predicate的使用

  泛型委托:表示定義一組條件并確定指定對象是否符合這些條件的方法。此委托由 Array 和 List 類的幾種方法使用,用于在集合中搜索元素。

? ? ? ? static void Main(string[] args)

? ? ? ? {

? ? ? ? ? ? Point[] points = { new Point(100, 200),

? ? ? ? ? ? new Point(150, 250), new Point(250, 375),

? ? ? ? ? ? new Point(275, 395), new Point(295, 450) };

? ? ? ? ? ? Point first = Array.Find(points, Product);

? ? ? ? ? ? Console.WriteLine("Found: X = {0}, Y = {1}", first.X, first.Y);

? ? ? ? ? ? Console.ReadKey();

? ? ? ? }

? ? ? ? private static bool Product(Point p)

? ? ? ? {

? ? ? ? ? ? if (p.X * p.Y > 100000)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return false;

? ? ? ? ? ? }

? ? ? ? }

  使用帶有 Array.Find 方法的 Predicate 委托搜索 Point 結(jié)構(gòu)的數(shù)組。如果 X 和 Y 字段的乘積大于 100,000,此委托表示的方法 ProductGT10 將返回 true。Find 方法為數(shù)組的每個(gè)元素調(diào)用此委托,在符合測試條件的第一個(gè)點(diǎn)處停止。

 3.委托的清空

  (1).在類中申明清空委托方法,依次循環(huán)去除委托引用。

???????? 方法如下:

? ? ? ? public MethodDelegate OnDelegate;? ? ? ? ? ? ? ?

? ? ? ? public void ClearDelegate()? ? ? ?

? ? ? ? {? ? ? ? ? ?

? ? ? ? ? ? while (this.OnDelegate != null)

? ? ? ? ? ? {? ? ? ? ? ? ? ?

? ? ? ? ? ? ? ? this.OnDelegate -= this.OnDelegate;?

? ? ? ? ? ? }? ? ? ?

? ? ? ? }

  (2).如果在類中沒有申明清空委托的方法,我們可以利用GetInvocationList查詢出委托引用,然后進(jìn)行去除。

  方法如下:


? ? ? ???public delegate void MethodDelegate();

? ? ? ? public static MethodDelegate OnDelegate;

? ? ? ? static void Main(string[] args)

? ? ? ? {

? ? ? ? ? ? if (OnDelegate != null)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? Delegate[] dels = test.OnDelegate.GetInvocationList();

? ? ? ? ? ? ? ? for (int i = 0; i < dels.Length; i++)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? test.OnDelegate -= dels[i] as MethodDelegate;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

4.委托的特點(diǎn)

  委托類似于 C++ 函數(shù)指針,但它們是類型安全的。

  委托允許將方法作為參數(shù)進(jìn)行傳遞。

  委托可用于定義回調(diào)方法。

  委托可以鏈接在一起;例如,可以對一個(gè)事件調(diào)用多個(gè)方法。

  方法不必與委托簽名完全匹配。

5.總結(jié):

  ??Delegate至少0個(gè)參數(shù),至多32個(gè)參數(shù),可以無返回值,也可以指定返回值類型

  Func可以接受0個(gè)至16個(gè)傳入?yún)?shù),必須具有返回值

  Action可以接受0個(gè)至16個(gè)傳入?yún)?shù),無返回值

  Predicate只能接受一個(gè)傳入?yún)?shù),返回值為bool類型

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,697評論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,853評論 18 399
  • 1.委托的聲明 Delegate可以指定返回值類型;Aciton無返回值類型;Func的最后一個(gè)參數(shù)表示返回值類型...
    混世小碼農(nóng)閱讀 438評論 0 1
  • 1. [C#語言基礎(chǔ)]請簡述拆箱和裝箱。 答: 裝箱操作: 值類型隱式轉(zhuǎn)換為object類型或由此值類型實(shí)現(xiàn)的任何...
    胤醚貔貅閱讀 4,989評論 1 28
  • 之前做過一些關(guān)于android播放器的開發(fā)工作,當(dāng)時(shí)懵懂無知,只知道一個(gè)ffmpeg,然后就費(fèi)勁巴拉的用ndk把f...
    ME_HK閱讀 18,969評論 7 9

友情鏈接更多精彩內(nèi)容