亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

c# 委托詳解

 更新時間:2017年02月07日 11:11:13   作者:liyongke  
本文將通過實例解析對c# 委托進行詳細介紹,具有很好的參考價值,下面跟著小編一起來看下吧

委托是一個類型。C#中的委托是面向?qū)ο蟮模⑶宜穷愋桶踩?當(dāng)創(chuàng)建委托實例的時候,創(chuàng)建的實例會包含一個調(diào)用列表,在調(diào)用列表中可以包含多個方法。每個方法稱作一個調(diào)用實體。調(diào)用實體可以是靜態(tài)方法,也可以是實例方法。如果是實例方法,則該調(diào)用實體包含調(diào)用該實例方法的實例。委托并不關(guān)心它所調(diào)用方法所屬的類,它只關(guān)心被調(diào)用方法與委托的類型是否兼容。 下面是代碼實例:

using System;
namespace LycheeTest{
 public delegate void D(int a, int b);
 public class Test {
 public D myDelegate;
 public Test() {
  myDelegate = new D(Show1);
 }
 private static void Show1(int a, int b) {
  Console.WriteLine("方法 Show1 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 private void Show2(int a, int b) {
  Console.WriteLine("方法 Show2 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 private void Show3(int a, int b) {
  Console.WriteLine("方法 Show3 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 }
 public class Program {
 static void Main(string[] args) {
  Test myT = new Test();
  myT.myDelegate(33, 22);
  Console.ReadKey();
 }
 }
}

這段代碼演示的是最簡單的一種委托形式。委托類型可以定義在類的外部,也可以定義在類的內(nèi)部。 本段代碼是定義在類的外部。第 3 行代碼定義的就是一個委托類型,委托類型的關(guān)鍵字是 delegate,關(guān)鍵字前是委托類型的訪問權(quán)限修飾符。關(guān)鍵字后是委托類型的返回類型,這個返回類型規(guī)定與委托類型兼容 的方法的返回類型必須與之相同。返回類型之后是委托類型的名稱。接下來是形參列表,它指定與委托類 型兼容的方法的參數(shù)類型和個數(shù)必須與之相同。第 5 行代碼定義了一個委托類型的變量,它是一個實例字段,訪問權(quán)限是 public 的。注意委托類型字段的訪問權(quán)限一定要比委托類型的訪問權(quán)限低或與委托類型的訪問權(quán)限相同才可以。第 9 行、第 12 行和第 15 行代碼定義了三個方法。其中第 9 行代碼是一個靜態(tài)方法。因為這段代碼演示的是最簡單的委托使用方法,所以只使用了其中的靜態(tài)方法。在第 6 行的構(gòu)造方法中,實例化了委托類型的變量,注意為委托變量的調(diào)用列表添加方法,只需要向其構(gòu)造方法中傳遞方法名稱即可。這是為委托添加調(diào)用方法的最基本的一種方法。第 21 行定義了 Test 類的一個實例,然后第 22 行調(diào)用了類的委托成員。在調(diào)用委托成員的時候,需要向其形參列表傳遞實參。這就是最基本的委托的使用方法。這段代碼的執(zhí)行結(jié)果如下:

方法 Show1 被調(diào)用,兩個實參相加的值是:55

下面再介紹一種委托類型的使用方法,實例代碼如下:

using System;
namespace LycheeTest {
 public delegate void D(int a, int b);
 public class Test {
 public static void Show1(int a, int b) {
  Console.WriteLine("方法 Show1 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 public void Show2(int a, int b) {
  Console.WriteLine("方法 Show2 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 public void Show3(int a, int b) {
  Console.WriteLine("方法 Show3 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 }
 public class Program {
 static void Main(string[] args) {
  Test myT = new Test();
  D myDelegate = new D(Test.Show1);
  D myDelegate1 = new D(myT.Show2);
  D myDelegate2 = new D(myT.Show3);
  myDelegate(22, 33);
  myDelegate1(33, 44);
  myDelegate2(55, 66);
  Console.ReadKey();
 }
 }
}

這段代碼取消了類中的委托類型字段,而是將委托類型作為一個類來看待。在包含入口點方法的類中,首先第 17 行定義了 Test 類的一個變量并做了實例化。因為要向委托傳遞類的實例方法,所以必須有類的實 例存在,才能引用類的實例方法。第 18 行定義了一個委托類型的變量,并實例化,這里需要注意,因為委托并不是類中的一個成員了, 所以向其構(gòu)造方法傳遞靜態(tài)方法的時候,需要以類名引用。第 19 行也定義了一個委托類型的變量,在向其傳遞實例方法的時候,需要以類的實例來引用。第 20 行代碼的情況同第 19 行代碼一樣。在向委托傳遞方法的時候,需要傳遞方法名,而不需要方法的形參列表。第 21 行到第 23 行是對委托的調(diào)用,這時要為其傳遞方法的實參。這段代碼的執(zhí)行結(jié)果如下:

方法 Show1 被調(diào)用,兩個實參相加的值是:55 
方法 Show2 被調(diào)用,兩個實參相加的值是:77 
方法 Show3 被調(diào)用,兩個實參相加的值是:121

委托的訪問修飾符

當(dāng)委托位于類的外部時,可以使用的訪問修飾符包括 public 和 internal。如果什么也不寫,默認是internal 的。當(dāng)委托位于類的內(nèi)部時,可以使用的訪問修飾符包括 public、protected、internal、protected

using System;
namespace LycheeTest{
 public class Test {
 protected delegate void D(int a, int b);
 private delegate void D1(int a, int b);
 protected internal delegate void D2(int a, int b);
 internal delegate void D3(int a, int b);
 private D myD;
 private D1 myD1;
 private D2 myD2;
 private D3 myD3;
 public Test() {
  myD = new D(Show1);
  myD1 = new D1(Show1);
  myD2 = new D2(Show1);
  myD3 = new D3(Show1);
 }
 public static void Show1(int a, int b) {
  Console.WriteLine("方法 Show1 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 public void Show2(int a, int b) {
  Console.WriteLine("方法 Show2 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 public void Show3(int a, int b) {
  Console.WriteLine("方法 Show3 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 public void Use() {
  myD(11, 12);
  myD1(22, 45);
  myD2(55, 78);
  myD3(345, 100);
 }
 }
 class Test1: Test {
 private D Test1D;
 private D2 Test1D2;
 private D3 Test1D3;
 public Test1() {
  Test1D = new D(Test.Show1);
  Test1D2 = new D2(Test.Show1);
  Test1D3 = new D3(Test.Show1);
 }
 public void Use1() {
  Test1D(22, 45);
  Test1D2(44, 45);
  Test1D3(77, 78);
 }
 }
 public class Program {
 static void Main(string[] args) {
  Test1 myT1 = new Test1();
  myT1.Use();
  myT1.Use1();
  Console.ReadKey();
 }
 }
}

代碼的第 4 行在類的內(nèi)部定義了委托類型,它作為類的成員定義,訪問權(quán)限是 protected,它可以被本類內(nèi)部訪問,也可以被派生類訪問。代碼的第 5 行定義的委托類型,訪問權(quán)限是 private 的,它只可以被本類內(nèi)部訪問。代碼的第 6 行定義的 protected internal 訪問權(quán)限的委托類型,可以被本程序集訪問, 還可以被派生類訪問,而不管派生類位于哪個程序集。第 7 行定義的委托類型是 internal 的,它只可以被本程序集訪問。因為所有這幾種委托類型都可以被本類內(nèi)部訪問,所以第 10 行到第 13 行定義了它們的變量。第 12 行的實例構(gòu)造方法中,對這四個委托類型的變量進行了實例化,并為它們的調(diào)用列表加入了方法 Show1。Show1 是一個靜態(tài)方法,但是在類內(nèi)部傳入委托類型的構(gòu)造方法時,不需要使用類名引用。第 27 行定義了實例方法,在方法內(nèi)部調(diào)用了這四個委托,并為其傳入實參。第 34 行代碼又定義了一個類,它繼承自基類 Test。因為基類中的委托類型只有 D、D2 和 D3 可以被派生類訪問,所以第 35 行到第 37 行定義了它們的變量。注意,雖然它們和基類中的委托變量是同一種類型, 但是它們是不同的委托。在第 38 行的實例構(gòu)造方法中,為這三個委托類型的變量創(chuàng)建實例,并為其調(diào)用列表加入方法,因為靜態(tài)方法 Show1 也被派生類所繼承,所以這里傳入的方法名,可以使用類名引用,也可以不使用類名引用。 第 43 行定義了一個實例方法,方法內(nèi)部調(diào)用了這三個委托,并為其傳入實參。第 51 行定義了派生類的實例,然后調(diào)用實例方法Use和Use1。這段代碼的執(zhí)行結(jié)果如下:

方法 Show1 被調(diào)用,兩個實參相加的值是:23 
方法 Show1 被調(diào)用,兩個實參相加的值是:67 
方法 Show1 被調(diào)用,兩個實參相加的值是:133
方法 Show1 被調(diào)用,兩個實參相加的值是:445 
方法 Show1 被調(diào)用,兩個實參相加的值是:67 
方法 Show1 被調(diào)用,兩個實參相加的值是:89 
方法 Show1 被調(diào)用,兩個實參相加的值是:155

因為 D 和 D2 的訪問權(quán)限被定義成了 protected 和 protected internal。所以下面來驗證在其它程序集中是否可以訪問它們。首先要將本段代碼中的包含 Main 方法的類去掉,然后在它的項目屬性中將它改變?yōu)轭悗?。接下來新建一個控制臺項目,并物理上引用這個類庫??刂婆_項目的代碼如下:

using System;
using LycheeTest;
namespace LycheeTest1{
 class Program: Test {
 private D pD;
 private D2 pD2;
 public Program() {
  pD = new D(Show1);
  pD2 = new D2(Show1);
 }
 public void Use3() {
  pD(34, 33);
  pD2(12, 11);
 }
 static void Main(string[] args) {
  Program p = new Program();
  p.Use3();
  Console.ReadKey();
 }
 }
}

因為第 3 行代碼的命名空間和類庫的命名空間是兩個獨立的命名空間,它們的成員不位于同一個命名空間內(nèi)。所以在一個命名空間內(nèi)引用另一個命名空間的成員時,需要加上另一個命名空間的名稱進行引用。 為了代碼編寫的方便,第 2 行代碼首先引用了類庫的命名空間。第 4 行代碼定義了一個類,它繼承自基類 Test。因為是派生類,所以對于委托類型 D 和 D2 都可以訪 問。第 5 行代碼和第 6 行代碼分別定義了 D 和 D2 的兩個變量。第 7 行的實例構(gòu)造方法對這兩個變量進行了實例化,并為其傳入方法 Show1。因為 Show1 方法被繼承了下來,所以這里不需要類名引用。第 11 行代碼定義了一個實例方法,它的作用是調(diào)用這兩個委托,并為其傳入實參。第 16 行代碼定義了本類的一個實例,并調(diào)用了實例方法 Use3。這段代碼的執(zhí)行結(jié)果如下:

方法 Show1 被調(diào)用,兩個實參相加的值是:67
方法 Show1 被調(diào)用,兩個實參相加的值是:23

類Test中的委托類型D2和D3都具有internal權(quán)限,現(xiàn)在來驗證一下,對于一個同一程序集中的非派生類是否可以訪問它們。首先將類庫更改回控制臺項目,然后增加一個類,這個類對于Test類來說是獨立的。它們之間只是位于一個程序集內(nèi),彼此沒有繼承關(guān)系。代碼如下:

using System;
namespace LycheeTest {
 public class Test {
 protected delegate void D(int a, int b);
 private delegate void D1(int a, int b);
 protected internal delegate void D2(int a, int b);
 internal delegate void D3(int a, int b);
 private D myD;
 private D1 myD1;
 private D2 myD2;
 private D3 myD3;
 public Test() {
  myD = new D(Show1);
  myD1 = new D1(Show1);
  myD2 = new D2(Show1);
  myD3 = new D3(Show1);
 }
 public static void Show1(int a, int b) {
  Console.WriteLine("方法 Show1 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 public void Show2(int a, int b) {
  Console.WriteLine("方法 Show2 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 public void Show3(int a, int b) {
  Console.WriteLine("方法 Show3 被調(diào)用,兩個實參相加的值是:{0}", a + b);
 }
 public void Use() {
  myD(11, 12);
  myD1(22, 45);
  myD2(55, 78);
  myD3(345, 100);
 }
 }
 class Test1 {
 private Test.D2 tD2;
 private Test.D3 tD3;
 public Test1() {
  tD2 = new Test.D2(Test.Show1);
  tD3 = new Test.D3(Test.Show1);
 }
 public void Use3() {
  tD2(34, 33);
  tD3(22, 21);
 }
 }
 public class Program {
 static void Main(string[] args) {
  Test1 myT1 = new Test1();
  myT1.Use3();
  Console.ReadKey();
 }
 }
}

這段代碼中,原來的類Test沒有進行修改。在第35行上,定義了一個類,它是一個相對于Test類來說獨立的類。它們的關(guān)系僅限于同在一個程序集內(nèi)。第 36 行代碼和第 37 行代碼定義了委托類型D2和D3的兩個變量。這里需要注意,因為這兩個類不是繼承關(guān)系,所以要引用Test類中的這兩個委托類型需要使用Test類的類名進行引用。第 38 行代碼是實例構(gòu)造方法,在構(gòu)造方法中將委托實例化。實例化委托類型的時候,仍然需要使用類名引用委托類型名,傳遞的方法名也是如此。第 行42 定義了一個實例方法,它調(diào)用了委托,并為其傳入了實參。第 49 行代碼定義了類Test1的一個實例,然后第 61 行調(diào)用類的實例方法。這段代碼的執(zhí)行結(jié)果如下:

方法 Show1 被調(diào)用,兩個實參相加的值是:67
方法 Show1 被調(diào)用,兩個實參相加的值是:43

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!

相關(guān)文章

最新評論