国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

編寫高質量代碼改善C#程序的157個建議——建議39:了解委托的實質

2019-11-14 14:05:34
字體:
來源:轉載
供稿:網友

建議39:了解委托的實質

理解C#中的委托需要把握兩個要點:

1)委托是方法指針。

2)委托是一個類,當對其進行實例化的時候,要將引用方法作為它的構造方法的參數。

設想這樣一個場景:在點對點文件傳輸過程當中,我們要設計一個文件傳輸類,該傳輸類起碼要滿足下面幾項功能:

  • 傳輸問題件;
  • 按照百分制通知傳輸進度;
  • 傳輸類能夠同時被控制臺程序和WinForm應用程序使用。

由于要讓通知本身能夠被控制臺程序和WinFrom應用程序使用,因此設計這個文件傳輸類在進行進度通知時,就不能顯示調用:

Console.WriteLine("當前進度:"+filePRogress);

或者

this.progressText.Text = "當前進度:" + fileProgress;

理想情況下是,在需要通知的地方,全部將其置換成一個方法的指針,由調用者來決定該方法完成什么功能。這個方法指針在C#中就是委托。可以像下面那樣聲明委托:

public delegate void FileUploadedHandler(int progress);

這個文件傳輸類可以寫成這樣:

    class FileUploader    {        public delegate void FileUploadedHandler(int progress);        public FileUploadedHandler FileUploaded;                public void Upload()        {            int fileProgress = 100;            while (fileProgress > 0)            {                //傳輸代碼,省略                fileProgress--;                if (FileUploaded != null)                {                    FileUploaded(fileProgress);                }            }        }    }

調用者在調用這個文件傳輸類的時候,應該同時為FileUploaded賦值,賦值過程中也就是將自身所具有的和委托聲明相同的聲明方法賦值給FileUploaded。這樣,類型FileUploader在執行到下面的代碼時,就是執行調用者自身的方法

 FileUploaded(fileProgress);

理解了“委托是方法指針”這一點后,在了理解“委托是一個類”。

查看下面這句話:

public delegate void FileUploadedHandler(int progress);

它的IL代碼為:

.class auto ansi sealed nested public FileUploadedHandler    extends [mscorlib]System.MulticastDelegate{    .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed    {    }    .method public hidebysig newslot virtual instance class [mscorlib]System.IAsyncResult BeginInvoke(int32 progress, class [mscorlib]System.AsyncCallback callback, object 'object') runtime managed    {    }    .method public hidebysig newslot virtual instance void EndInvoke(class [mscorlib]System.IAsyncResult result) runtime managed    {    }    .method public hidebysig newslot virtual instance void Invoke(int32 progress) runtime managed    {    }}

調用委托方法:

FileUploaded(fileProgress);

其實是調用:

FileUploaded.Invok(fileProgress);

可以查看Upload方法的IL代碼:

.method public hidebysig instance void Upload() cil managed{    .maxstack 2    .locals init (        [0] int32 fileProgress,        [1] bool CS$4$0000)    L_0000: nop     L_0001: ldc.i4.s 100    L_0003: stloc.0     L_0004: br.s L_0028    L_0006: nop     L_0007: ldloc.0     L_0008: ldc.i4.1     L_0009: sub     L_000a: stloc.0     L_000b: ldarg.0     L_000c: ldfld class MyTest.FileUploader/FileUploadedHandler MyTest.FileUploader::FileUploaded    L_0011: ldnull     L_0012: ceq     L_0014: stloc.1     L_0015: ldloc.1     L_0016: brtrue.s L_0027    L_0018: nop     L_0019: ldarg.0     L_001a: ldfld class MyTest.FileUploader/FileUploadedHandler MyTest.FileUploader::FileUploaded    L_001f: ldloc.0     L_0020: callvirt instance void MyTest.FileUploader/FileUploadedHandler::Invoke(int32)    L_0025: nop     L_0026: nop     L_0027: nop     L_0028: ldloc.0     L_0029: ldc.i4.0     L_002a: cgt     L_002c: stloc.1     L_002d: ldloc.1     L_002e: brtrue.s L_0006    L_0030: ret }

可以看到L_0020處調用Invoke方法。

 

一句話:委托是一種數據類型,它用來傳遞方法。

 

轉自:《編寫高質量代碼改善C#程序的157個建議》陸敏技


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 革吉县| 文成县| 南华县| 韩城市| 桑日县| 乐至县| 拜泉县| 胶州市| 二连浩特市| 吉隆县| 德格县| 夏邑县| 衡阳市| 汝南县| 尼勒克县| 霍邱县| 闽清县| 大城县| 颍上县| 中西区| 湘阴县| 宣武区| 邵阳县| 宜昌市| 祥云县| 喀喇| 岢岚县| 中牟县| 合阳县| 若尔盖县| 西充县| 布拖县| 郯城县| 洞口县| 崇文区| 青岛市| 安阳市| 闽清县| 赤壁市| 大渡口区| 绥化市|