程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 深刻懂得C#中的Delegate

深刻懂得C#中的Delegate

編輯:C#入門知識

深刻懂得C#中的Delegate。本站提示廣大學習愛好者:(深刻懂得C#中的Delegate)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻懂得C#中的Delegate正文


在c#中,event與delegate是兩個異常主要的概念。由於在Windows運用法式中,對事宜的應用異常頻仍,而事宜的完成依附於delegate。

上面是對網上一些比擬好的關於delegage的材料的整頓,和本身的一些設法主意。

Delegate是甚麼?

   Delegate中文翻譯為“拜托”。Msdn中對Delegate的說明以下:

    C#中的拜托相似於C或C++中的函數指針。應用拜托使法式員可以將辦法援用封裝在拜托對象內。然後可以將該拜托對象傳遞給可挪用所援用辦法的代碼,而不用在編譯時曉得將挪用哪一個辦法。與C或C++中的函數指針分歧,拜托是面向對象、類型平安的,而且是平安的。

一旦為拜托分派了辦法,拜托將與該辦法具有完整雷同的行動。拜托辦法的應用可以像其他任何辦法一樣,具有參數和前往值,以下面的示例所示:

public delegate void Del(string message);

與拜托的簽名(由前往類型和參數構成)婚配的任何辦法都可以分派給該拜托。如許便可以經由過程編程方法來更改辦法挪用,還可以向現有類中拔出新代碼。只需曉得拜托的簽名,即可以分派本身的拜托辦法。

挪用拜托

結構拜托對象時,平日供給拜托將包裝的辦法的稱號或應用匿名辦法。實例化拜托後,拜托將把對它停止的辦法挪用傳遞給辦法。挪用方傳遞給拜托的參數被傳遞給辦法,來自辦法的前往值(假如有)由拜托前往給挪用方。這被稱為挪用拜托。可以將一個實例化的拜托視為被包裝的辦法自己來挪用該拜托。例如:

// Create a method for a delegate.
public static void DelegateMethod(string message)
{
System.Console.WriteLine(message);
}
// Instantiate the delegate.
Del handler = DelegateMethod;
// Call the delegate.
handler("Hello World");

將拜托結構為包裝實例辦法時,該拜托將同時援用實例和辦法。除它所包裝的辦法外,拜托不懂得實例類型,所以只需隨意率性類型的對象中具有與拜托簽名相婚配的辦法,拜托便可以援用該對象。將拜托結構為包裝靜態辦法時,它只援用辦法。

回調

因為實例化拜托是一個對象,所以可以將其作為參數停止傳遞,也能夠將其賦值給屬性。如許,辦法即可以將一個拜托作為參數來接收,而且今後可以挪用該拜托。這稱為異步回調,是在較長的過程完成後用來告訴挪用方的經常使用辦法。以這類方法應用拜托時,應用拜托的代碼無需懂得有關所用辦法的完成方面的任何信息。此功效相似於接口所供給的封裝。

回調的另外一個罕見用法是界說自界說的比擬辦法並將該拜托傳遞給排序辦法。它許可挪用方的代碼成為排序算法的一部門。上面的示例辦法應用 Del 類型作為參數:

public void MethodWithCallback(int param1, int param2, Del callback)
{
callback("The number is: " + (param1 + param2).ToString());
}

然後可以將下面創立的拜托傳遞給該辦法:

MethodWithCallback(1, 2, handler);

在掌握台中將收到上面的輸入:

The number is: 3

應用拜托的利益

拜托許可類設計器分別類型聲明和完成。

在將拜托用作籠統概念時,MethodWithCallback 不須要直接挪用掌握台 -- 設計它時無需斟酌掌握台。MethodWithCallback 的感化只是預備字符串並將該字符串傳遞給其他辦法。此功效特殊壯大,由於拜托的辦法可使用隨意率性數目的參數。

將辦法作為參數停止援用的才能使拜托成為界說回調辦法的幻想選擇。例如,可以向排序算法傳遞比較較兩個對象的辦法的援用。分別比擬代碼使得可以采取更通用的方法編寫算法。

若何應用拜托

1. 聲明拜托

聲明一個新的拜托類型。每一個拜托類型都描寫參數的數量和類型,和它可以封裝的辦法的前往值類型。每當須要一組新的參數類型或新的前往值類型時,都必需聲明一個新的拜托類型。

2. 實例化拜托

聲清楚明了拜托類型後,必需創立拜托對象並使之與特定辦法聯系關系。辦法的簽名應與拜托界說的簽名分歧。

拜托對象可以聯系關系靜態辦法,也能夠聯系關系非靜態辦法。

拜托一旦創立,它的聯系關系辦法就不克不及更改;拜托對象是弗成變的。

3. 挪用拜托

創立拜托對象後,平日將拜托對象傳遞給將挪用該拜托的其他代碼。經由過程拜托對象的稱號(前面隨著要傳遞給拜托的參數,括在括號內)挪用拜托對象。

上面是一個示例:

using System;
public class SamplesDelegate
{
// Declares a delegate for a method that takes in an int and returns a String.
public delegate String myMethodDelegate(int myInt);
// Defines some methods to which the delegate can point.
public class mySampleClass
{
// Defines an instance method.
public String myStringMethod(int myInt)
{
if (myInt > 0)
return ("positive");
if (myInt < 0)
return ("negative");
return ("zero");
}
// Defines a static method.
public static String mySignMethod(int myInt)
{
if (myInt > 0)
return ("+");
if (myInt < 0)
return ("-");
return ("");
}
}
public static void Main()
{
// Creates one delegate for each method.
mySampleClass mySC = new mySampleClass();
myMethodDelegate myD1 = new myMethodDelegate(mySC.myStringMethod);
myMethodDelegate myD2 = new myMethodDelegate(mySampleClass.mySignMethod);
// Invokes the delegates.
Console.WriteLine("{0} is {1}; use the sign /"{2}/".", 5, myD1(5), myD2(5));
Console.WriteLine("{0} is {1}; use the sign /"{2}/".", -3, myD1(-3), myD2(-3));
Console.WriteLine("{0} is {1}; use the sign /"{2}/".", 0, myD1(0), myD2(0));
}
}
/*
This code produces the following output:
5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/

多路播送

挪用拜托時,它可以挪用多個辦法。這稱為多路播送。若要向拜托的辦法列表(挪用列表)中添加額定的辦法,只需應用加法運算符或加法賦值運算符(“+”或“+=”)添加兩個拜托。例如:

MethodClass obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod;
//Both types of assignment are valid.
Del allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;

此時,allMethodsDelegate 在其挪用列表中包括三個辦法 -- Method1、Method2 和 DelegateMethod。本來的三個拜托 d1、d2 和 d3 堅持不變。挪用 allMethodsDelegate 時,將按次序挪用一切這三個辦法。假如拜托應用援用參數,則援用將順次傳遞給三個辦法中的每一個辦法,由一個辦法惹起的更改對下一個辦法是可見的。假如任一辦法激發了異常,而在該辦法內未捕捉該異常,則該異常將傳遞給拜托的挪用方,而且不再對換用列表中前面的辦法停止挪用。假如拜托具有前往值和/或輸入參數,它將前往最初挪用的辦法的前往值和參數。若要從挪用列表中移除辦法,請應用減法運算符或減法賦值運算符(“-”或“-=”)。例如:

//remove Method1
allMethodsDelegate -= d1;
// copy AllMethodsDelegate while removing d2
Del oneMethodDelegate = allMethodsDelegate - d2;

多路播送拜托普遍用於事宜處置中。事宜源對象向已注冊吸收該事宜的吸收方對象發送事宜告訴。為了為事宜注冊,吸收方創立了旨在處置事宜的辦法,然後為該辦法創立拜托並將該拜托傳遞給事宜源。事宜產生時,源將挪用拜托。然後,拜托挪用吸收方的事宜處置辦法並傳送事宜數據。給定事宜的拜托類型由事宜源界說。
本示例演示若何組合多路播送拜托。拜托對象的一個用處在於,可使用 + 運算符將它們分派給一個要成為多路播送拜托的拜托實例。組合的拜托可挪用構成它的那兩個拜托。只要雷同類型的拜托才可以組合。

運算符可用來從組合的拜托移除組件拜托。

delegate void Del(string s); 
class TestClass
{
static void Hello(string s)
{
System.Console.WriteLine(" Hello, {0}!", s);
}
static void Goodbye(string s)
{
System.Console.WriteLine(" Goodbye, {0}!", s);
}
static void Main()
{
Del a, b, c, d;
// Create the delegate object a that references
// the method Hello:
a = Hello;
// Create the delegate object b that references
// the method Goodbye:
b = Goodbye;
// The two delegates, a and b, are composed to form c:
c = a + b;
// Remove a from the composed delegate, leaving d,
// which calls only the method Goodbye:
d = c - a;
System.Console.WriteLine("Invoking delegate a:");
a("A");
System.Console.WriteLine("Invoking delegate b:");
b("B");
System.Console.WriteLine("Invoking delegate c:");
c("C");
System.Console.WriteLine("Invoking delegate d:");
d("D");
}
}

Delegate的總結

delegate是C#中的一品種型,它現實上是一個可以或許持有對某個辦法的援用的類。與其它的類分歧,delegate類可以或許具有一個簽名(signature),而且它只能持有與它的簽名相婚配的辦法的援用。它所完成的功效與C/C++中的函數指針非常類似。它許可傳遞一個類A的辦法m給另外一個類B的對象,使得類B的對象可以或許挪用這個辦法m。但與函數指針比擬,delegate有很多函數指針不具有的長處。起首,函數指針只能指向靜態函數,而delegate既可以援用靜態函數,又可以援用非靜態成員函數。在援用非靜態成員函數時,delegate不只保留了對此函數進口指針的援用,並且還保留了挪用此函數的類實例的援用。其次,與函數指針比擬,delegate是面向對象、類型平安、靠得住的受控(managed)對象。也就是說,runtime可以或許包管delegate指向一個有用的辦法,你不必擔憂delegate會指向有效地址或許越界地址。

本身對Delegate的懂得

“delegate是C#中的一品種型。”delegate與class是相似的,class界說一品種型,delegate也界說一品種型。class可以界說各類各樣的類,如classA、classB,而delegate可以界說各類各樣的署理,如delegate1,delegate2。與class分歧的是,delegate的界說沒有字段、屬性、辦法等,只要簽名(前往值及參數)。

“它現實上是一個可以或許持有對某個辦法的援用的類。”delegate對象可以持有對某個辦法的援用,這個辦法的簽名必需與署理類型的簽名分歧(這就是“delegate界說回調辦法的接口”這一說法的緣由)。署理對象持有對這個辦法的援用,當挪用署理對象時,即完成對這個辦法的挪用。之所以能經由過程挪用署理對象來完成對辦法的挪用,是由於在實例化署理對象時,把傳入辦法的地址賦給了署理對象,使適合挪用署理對象時,內存中的指令指針即指向傳入辦法的進口,履行傳入辦法的辦法體。

應用署理來完成多路播送時,即把多個辦法的援用(即內存地址)保留到署理的辦法援用隊列。挪用署理對象時,依據署理對象的辦法援用隊列,內存中的指令指針即逐一指向每一個辦法的進口,順次序履行每一個辦法的辦法體。

事宜的宣布與定閱。所謂事宜,就是指當某個特定的工作產生時,類或對象經由過程事宜告訴存眷此工作的類或對象。發送(或激發)事宜的類稱為“刊行者”,吸收(或處置)事宜的類稱為“定戶”。事宜的完成是依附於署理的。事宜的完成道理即,定戶把呼應事宜的辦法傳遞給刊行者,當特定的工作產生時,刊行者可以或許挪用這些呼應事宜的辦法。在代碼級的完成即,刊行者界說一個delegate類型,供給一個public的delegate對象作為字段或屬性;定戶(可所以多個)經由過程將呼應事宜的辦法傳遞給delegate類型來實例化一個delegate對象,並經由過程+=運算符,將delegate對象賦值給刊行者的delegate對象,現實上就是多路播送。當特定的工作產生時,刊行者挪用delegate對象,即挪用一切定戶的呼應事宜的辦法。

以上所述是小編給年夜家引見的深刻懂得C#中的Delegate ,願望對年夜家有所贊助,假如年夜家有任何疑問請給我留言,小編會實時答復年夜家的。在此也異常感激年夜家對網站的支撐!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved