c#中心根底-委托。本站提示廣大學習愛好者:(c#中心根底-委托)文章只能為提供參考,不一定能成為您想要的結果。以下是c#中心根底-委托正文
委托是一個類型。C#中的委托是面向對象的,並且它是類型平安的 當創立委托實例的時分,創立的實例會包括一個調用列表,在調用列表中可以包括多個辦法。每個辦法稱作一個調用實體。調用實體可以是靜態辦法,也可以是實例辦法。假如是實例辦法,則該調用實體包括調用該實例辦法的實例。委托並不關懷它所調用辦法所屬的類,它只關懷被調用辦法與委托的類型能否兼容。 上面是代碼實例:
1 using System; 2 namespace LycheeTest{ 3 public delegate void D(int a, int b); 4 public class Test { 5 public D myDelegate; 6 public Test() { 7 myDelegate = new D(Show1); 8 } 9 private static void Show1(int a, int b) { 10 Console.WriteLine("辦法 Show1 被調用,兩個實參相加的值是:{0}", a + b); 11 } 12 private void Show2(int a, int b) { 13 Console.WriteLine("辦法 Show2 被調用,兩個實參相加的值是:{0}", a + b); 14 } 15 private void Show3(int a, int b) { 16 Console.WriteLine("辦法 Show3 被調用,兩個實參相加的值是:{0}", a + b); 17 } 18 } 19 public class Program { 20 static void Main(string[] args) { 21 Test myT = new Test(); 22 myT.myDelegate(33, 22); 23 Console.ReadKey(); 24 } 25 } 26 27 }
這段代碼演示的是最復雜的一種委托方式。委托類型可以定義在類的內部,也可以定義在類的外部。 本段代碼是定義在類的內部。第 3 行代碼定義的就是一個委托類型,委托類型的關鍵字是 delegate,關鍵字前是委托類型的訪問權限修飾符。關鍵字後是委托類型的前往類型,這個前往類型規則與委托類型兼容 的辦法的前往類型必需與之相反。前往類型之後是委托類型的稱號。接上去是形參列表,它指定與委托類 型兼容的辦法的參數類型和個數必需與之相反。第 5 行代碼定義了一個委托類型的變量,它是一個實例字段,訪問權限是 public 的。留意委托類型字段的訪問權限一定要比委托類型的訪問權限低或與委托類型的訪問權限相反才可以。第 9 行、第 12 行和第 15 行代碼定義了三個辦法。其中第 9 行代碼是一個靜態辦法。由於這段代碼演示的是最復雜的委托運用辦法,所以只運用了其中的靜態辦法。在第 6 行的結構辦法中,實例化了委托類型的變量,留意為委托變量的調用列表添加辦法,只需求向其結構辦法中傳遞辦法稱號即可。這是為委托添加調用辦法的最根本的一種辦法。第 21 行定義了 Test 類的一個實例,然後第 22 行調用了類的委托成員。在調用委托成員的時分,需求向其形參列表傳遞實參。這就是最根本的委托的運用辦法。這段代碼的執行後果如下:
辦法 Show1 被調用,兩個實參相加的值是:55
上面再引見一種委托類型的運用辦法,實例代碼如下:
1 using System; 2 namespace LycheeTest { 3 public delegate void D(int a, int b); 4 public class Test { 5 public static void Show1(int a, int b) { 6 Console.WriteLine("辦法 Show1 被調用,兩個實參相加的值是:{0}", a + b); 7 } 8 public void Show2(int a, int b) { 9 Console.WriteLine("辦法 Show2 被調用,兩個實參相加的值是:{0}", a + b); 10 } 11 public void Show3(int a, int b) { 12 Console.WriteLine("辦法 Show3 被調用,兩個實參相加的值是:{0}", a + b); 13 } 14 } 15 public class Program { 16 static void Main(string[] args) { 17 Test myT = new Test(); 18 D myDelegate = new D(Test.Show1); 19 D myDelegate1 = new D(myT.Show2); 20 D myDelegate2 = new D(myT.Show3); 21 myDelegate(22, 33); 22 myDelegate1(33, 44); 23 myDelegate2(55, 66); 24 Console.ReadKey(); 25 } 26 } 27 28 }
這段代碼取消了類中的委托類型字段,而是將委托類型作為一個類來對待。在包括入口點辦法的類中,首先第 17 行定義了 Test 類的一個變量並做了實例化。由於要向委托傳遞類的實例辦法,所以必需有類的實 例存在,才干援用類的實例辦法。第 18 行定義了一個委托類型的變量,並實例化,這裡需求留意,由於委托並不是類中的一個成員了, 所以向其結構辦法傳遞靜態辦法的時分,需求以類名援用。第 19 行也定義了一個委托類型的變量,在向其傳遞實例辦法的時分,需求以類的實例來援用。第 20 行代碼的狀況同第 19 行代碼一樣。在向委托傳遞辦法的時分,需求傳遞辦法名,而不需求辦法的形參列表。第 21 行到第 23 行是對委托的調用,這時要為其傳遞辦法的實參。這段代碼的執行後果如下:
辦法 Show1 被調用,兩個實參相加的值是:55 辦法 Show2 被調用,兩個實參相加的值是:77 辦法 Show3 被調用,兩個實參相加的值是:121委托的訪問修飾符
當委托位於類的內部時,可以運用的訪問修飾符包括 public 和 internal。假如什麼也不寫,默許是internal 的。當委托位於類的外部時,可以運用的訪問修飾符包括 public、protected、internal、protected
1 using System; 2 namespace LycheeTest{ 3 public class Test { 4 protected delegate void D(int a, int b); 5 private delegate void D1(int a, int b); 6 protected internal delegate void D2(int a, int b); 7 internal delegate void D3(int a, int b); 8 private D myD; 9 private D1 myD1; 10 private D2 myD2; 11 private D3 myD3; 12 public Test() { 13 myD = new D(Show1); 14 myD1 = new D1(Show1); 15 myD2 = new D2(Show1); 16 myD3 = new D3(Show1); 17 } 18 public static void Show1(int a, int b) { 19 Console.WriteLine("辦法 Show1 被調用,兩個實參相加的值是:{0}", a + b); 20 } 21 public void Show2(int a, int b) { 22 Console.WriteLine("辦法 Show2 被調用,兩個實參相加的值是:{0}", a + b); 23 } 24 public void Show3(int a, int b) { 25 Console.WriteLine("辦法 Show3 被調用,兩個實參相加的值是:{0}", a + b); 26 } 27 public void Use() { 28 myD(11, 12); 29 myD1(22, 45); 30 myD2(55, 78); 31 myD3(345, 100); 32 } 33 } 34 class Test1: Test { 35 private D Test1D; 36 private D2 Test1D2; 37 private D3 Test1D3; 38 public Test1() { 39 Test1D = new D(Test.Show1); 40 Test1D2 = new D2(Test.Show1); 41 Test1D3 = new D3(Test.Show1); 42 } 43 public void Use1() { 44 Test1D(22, 45); 45 Test1D2(44, 45); 46 Test1D3(77, 78); 47 } 48 } 49 public class Program { 50 static void Main(string[] args) { 51 Test1 myT1 = new Test1(); 52 myT1.Use(); 53 myT1.Use1(); 54 Console.ReadKey(); 55 } 56 } 57 }
代碼的第 4 行在類的外部定義了委托類型,它作為類的成員定義,訪問權限是 protected,它可以被本類外部訪問,也可以被派生類訪問。代碼的第 5 行定義的委托類型,訪問權限是 private 的,它只可以被本類外部訪問。代碼的第 6 行定義的 protected internal 訪問權限的委托類型,可以被本順序集訪問, 還可以被派生類訪問,而不論派生類位於哪個順序集。第 7 行定義的委托類型是 internal 的,它只可以被本順序集訪問。由於一切這幾種委托類型都可以被本類外部訪問,所以第 10 行到第 13 行定義了它們的變量。第 12 行的實例結構辦法中,對這四個委托類型的變量停止了實例化,並為它們的調用列表參加了辦法 Show1。Show1 是一個靜態辦法,但是在類外部傳入委托類型的結構辦法時,不需求運用類名援用。第 27 行定義了實例辦法,在辦法外部調用了這四個委托,並為其傳入實參。第 34 行代碼又定義了一個類,它承繼自基類 Test。由於基類中的委托類型只要 D、D2 和 D3 可以被派生類訪問,所以第 35 行到第 37 行定義了它們的變量。留意,雖然它們和基類中的委托變量是同一品種型, 但是它們是不同的委托。在第 38 行的實例結構辦法中,為這三個委托類型的變量創立實例,並為其調用列表參加辦法,由於靜態辦法 Show1 也被派生類所承繼,所以這裡傳入的辦法名,可以運用類名援用,也可以不運用類名援用。 第 43 行定義了一個實例辦法,辦法外部調用了這三個委托,並為其傳入實參。第 51 行定義了派生類的實例,然後調用實例辦法Use和Use1。這段代碼的執行後果如下:
辦法 Show1 被調用,兩個實參相加的值是:23 辦法 Show1 被調用,兩個實參相加的值是:67 辦法 Show1 被調用,兩個實參相加的值是:133 辦法 Show1 被調用,兩個實參相加的值是:445 辦法 Show1 被調用,兩個實參相加的值是:67 辦法 Show1 被調用,兩個實參相加的值是:89 辦法 Show1 被調用,兩個實參相加的值是:155
由於 D 和 D2 的訪問權限被定義成了 protected 和 protected internal。所以上面來驗證在其它順序集中能否可以訪問它們。首先要將本段代碼中的包括 Main 辦法的類去掉,然後在它的項目屬性中將它改動為類庫。接上去新建一個控制台項目,並物理上援用這個類庫。控制台項目的代碼如下:
1 using System; 2 using LycheeTest; 3 namespace LycheeTest1{ 4 class Program: Test { 5 private D pD; 6 private D2 pD2; 7 public Program() { 8 pD = new D(Show1); 9 pD2 = new D2(Show1); 10 } 11 public void Use3() { 12 pD(34, 33); 13 pD2(12, 11); 14 } 15 static void Main(string[] args) { 16 Program p = new Program(); 17 p.Use3(); 18 Console.ReadKey(); 19 } 20 } 21 }
由於第 3 行代碼的命名空間和類庫的命名空間是兩個獨立的命名空間,它們的成員不位於同一個命名空間內。所以在一個命名空間內援用另一個命名空間的成員時,需求加上另一個命名空間的稱號停止援用。 為了代碼編寫的方便,第 2 行代碼首先援用了類庫的命名空間。第 4 行代碼定義了一個類,它承繼自基類 Test。由於是派生類,所以關於委托類型 D 和 D2 都可以訪 問。第 5 行代碼和第 6 行代碼辨別定義了 D 和 D2 的兩個變量。第 7 行的實例結構辦法對這兩個變量停止了實例化,並為其傳入辦法 Show1。由於 Show1 辦法被承繼了上去,所以這裡不需求類名援用。第 11 行代碼定義了一個實例辦法,它的作用是調用這兩個委托,並為其傳入實參。第 16 行代碼定義了本類的一個實例,並調用了實例辦法 Use3。這段代碼的執行後果如下:
辦法 Show1 被調用,兩個實參相加的值是:67 辦法 Show1 被調用,兩個實參相加的值是:23類Test中的委托類型D2和D3都具有internal權限,如今來驗證一下,關於一個同一順序集中的非派生類能否可以訪問它們。首先將類庫更改回控制台項目,然後添加一個類,這個類關於Test類來說是獨立的。它們之間只是位於一個順序集內,彼此沒有承繼關系。代碼如下:
1 using System; 2 namespace LycheeTest { 3 public class Test { 4 protected delegate void D(int a, int b); 5 private delegate void D1(int a, int b); 6 protected internal delegate void D2(int a, int b); 7 internal delegate void D3(int a, int b); 8 private D myD; 9 private D1 myD1; 10 private D2 myD2; 11 private D3 myD3; 12 public Test() { 13 myD = new D(Show1); 14 myD1 = new D1(Show1); 15 myD2 = new D2(Show1); 16 myD3 = new D3(Show1); 17 } 18 public static void Show1(int a, int b) { 19 Console.WriteLine("辦法 Show1 被調用,兩個實參相加的值是:{0}", a + b); 20 } 21 public void Show2(int a, int b) { 22 Console.WriteLine("辦法 Show2 被調用,兩個實參相加的值是:{0}", a + b); 23 } 24 public void Show3(int a, int b) { 25 Console.WriteLine("辦法 Show3 被調用,兩個實參相加的值是:{0}", a + b); 26 } 27 public void Use() { 28 myD(11, 12); 29 myD1(22, 45); 30 myD2(55, 78); 31 myD3(345, 100); 32 } 33 } 34 35 class Test1 { 36 private Test.D2 tD2; 37 private Test.D3 tD3; 38 public Test1() { 39 tD2 = new Test.D2(Test.Show1); 40 tD3 = new Test.D3(Test.Show1); 41 } 42 public void Use3() { 43 tD2(34, 33); 44 tD3(22, 21); 45 } 46 } 47 public class Program { 48 static void Main(string[] args) { 49 Test1 myT1 = new Test1(); 50 myT1.Use3(); 51 Console.ReadKey(); 52 } 53 } 54 }
這段代碼中,原來的類Test沒有停止修正。在第35行上,定義了一個類,它是一個絕對於Test類來說獨立的類。它們的關系僅限於同在一個順序集內。第 36 行代碼和第 37 行代碼定義了委托類型D2和D3的兩個變量。這裡需求留意,由於這兩個類不是承繼關系,所以要援用Test類中的這兩個委托類型需求運用Test類的類名停止援用。第 38 行代碼是實例結構辦法,在結構辦法中將委托實例化。實例化委托類型的時分,依然需求運用類名援用委托類型名,傳遞的辦法名也是如此。第 行42 定義了一個實例辦法,它調用了委托,並為其傳入了實參。第 49 行代碼定義了類Test1的一個實例,然後第 61 行調用類的實例辦法。這段代碼的執行後果如下:
辦法 Show1 被調用,兩個實參相加的值是:67 辦法 Show1 被調用,兩個實參相加的值是:43