C#拜托與事宜初探。本站提示廣大學習愛好者:(C#拜托與事宜初探)文章只能為提供參考,不一定能成為您想要的結果。以下是C#拜托與事宜初探正文
拜托給了C#操作函數的靈巧性,我們可以使用拜托像操作變量一樣來操作函數,其實這個功效其實不是C#的開創,早在C++時期就有函數指針這一說法,而在我看來拜托就是C#的函數指針,起首先扼要的引見一下拜托的根本常識:
拜托的界說
拜托的聲明原型是
delegate <函數前往類型> <拜托名> (<函數參數>)
例子:public delegate void CheckDelegate(int number);//界說了一個拜托CheckDelegate,它可以注冊前往void類型且有一個int作為參數的函數
如許就界說了一個拜托,然則拜托在.net內相當於聲清楚明了一個類(在前面的代碼中會講到確切如斯),類假如不實例化為對象,許多功效是沒有方法應用的,拜托也是如斯.
拜托的實例化
拜托實例化的原型是
<拜托類型> <實例假名>=new <拜托類型>(<注冊函數>)
例子:CheckDelegate _checkDelegate=new CheckDelegate(CheckMod);//用函數CheckMod實例化下面的CheckDelegate 拜托為_checkDelegate
在.net 2.0開端可以直接用婚配的函數實例化拜托:
<拜托類型> <實例假名>=<注冊函數>
例子:CheckDelegate _checkDelegate=CheckMod;//用函數CheckMod實例化下面的CheckDelegate 拜托為_checkDelegate
如今我們便可以像應用函數一樣來應用拜托了,在下面的例子中如今履行_checkDelegate()就同等於履行CheckMod(),最症結的是如今函數CheckMod相當於放在了變量傍邊,它可以傳遞給其它的CheckDelegate援用對象,並且可以作為函數參數傳遞到其他函數內,也能夠作為函數的前往類型
事宜是拜托的一種特別情勢,當產生成心義的工作時,事宜處置對象告訴進程。
一.C說話中的函數指針
想要懂得甚麼是拜托,就要先懂得函數指針的概念。所謂函數指針,就是指向函數的指針(等於沒說-.-)。好比我界說了兩個函數square和cube分離用於盤算一個數的平方和立方,我再界說函數指針calcu,然後我讓calcu指向square,那末挪用calcu時就相當於挪用了square函數(留意,此處函數指針接收的參數類型及個數要與函數分歧)。很好懂得吧?不多說,上代碼。
#include <stdio.h> void square(int x) { printf("square of %d is %d\n",x,x*x); } void cube(int x) { printf("cube of %d is %d\n",x,x*x*x); } int main() { void (*calcu)(int x); calcu=square; calcu(); return ; }
二.C#中拜托的本質
拜托別名拜托類型,為何C#弄出這個器械?由於C#是一門比擬平安的說話,不許可操作指針,因而我們不克不及界說函數指針。但想要到達雷同的後果,因而界說了拜托類型。所謂拜托類型,其實質就是C中的指針類型。因而代碼釀成了如許:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Delegate { class Program { static void square(int x) { Console.WriteLine("square of {} is {}", x, x * x); } static void cube(int x) { Console.WriteLine("cube of {} is {}", x, x * x * x); } delegate void math(int x); //界說拜托類型 static void Main(string[] args) { math calcu; calcu += square; calcu(); Console.ReadKey(); } } }
可以看出,界說拜托類型math現實上就相當於界說了void*類型。而拜托類型實例化獲得的calcu現實上就是函數指針。(說句題外話:界說函數(辦法)時要加上static是由於挪用函數時並未實例化,只要靜態辦法可以或許直接經由過程類挪用)。
三.拜托的應用辦法
我們在上述代碼19行前面加上一行代碼 calcu+=cube; 運轉會發明,square和cube均被挪用。可以看出,符號 += 表現綁定辦法到拜托變量,同理符號 -= 表現撤消綁定。可以懂得為calcu是void **類型,即它指向了一個數組,數組中的每項都是函數指針類型,每次挪用calcu時,遍歷此數組,即順次挪用每一個綁定的辦法。
四.封裝與事宜的引入
上面我們要用面向對象的思惟將上述代碼停止封裝,使其變清楚。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Delegate { public delegate void math(int x); public class Calcu { public math calcu; } class Program { static void square(int x) { Console.WriteLine("square of {} is {}", x, x * x); } static void cube(int x) { Console.WriteLine("cube of {} is {}", x, x * x * x); } static void Main(string[] args) { Calcu c = new Calcu(); c.calcu += square; c.calcu += cube; c.calcu(); Console.ReadKey(); } } }
因為拜托變量是public的,封裝的水平很低,在內部可以隨意率性修正。為了改良這個成績,C#引入了事宜。
所謂事宜,現實上照樣拜托的實例化,只是其外部多了一些界說,多了一些限制。其一,事宜現實上聲清楚明了一個private類型的拜托變量,是以在類外沒法直接挪用。
因而我們將上述代碼的第12行改成如許:
public event math calcu;
運轉以後25行報錯了,由於calcu是private的,不克不及直接挪用。但23,24行並沒有報錯。那末成績來了,為何我們可以用+=來給calcu綁定辦法呢?
由於其二,事宜還幫我們干了一件工作,就是界說了綁定辦法和撤消綁定辦法的函數,它們是public的,而且將運算符+=,-=重載,和這兩個函數對應。
好了,如今我們要寫一個接口函數來完成盤算:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Delegate { public delegate void math(int x); public class Calcu { public event math calcu; public void calculate(int x) { calcu(x); } } class Program { static void square(int x) { Console.WriteLine("square of {} is {}", x, x * x); } static void cube(int x) { Console.WriteLine("cube of {} is {}", x, x * x * x); } static void Main(string[] args) { Calcu c = new Calcu(); c.calcu += square; c.calcu += cube; c.calculate(); Console.ReadKey(); } } }
至此,根本概念曾經清楚。
想來,應用事宜會讓人不能不將對象封裝起來,這應當就是面向對象思惟的表現吧。
以上內容是針對C#拜托與事宜初探的相干常識,願望對年夜家有所贊助。