Recommendation 39: Understanding the nature of the mandate
Understanding a delegate in C # requires two key points:
1) The delegate is a method pointer.
2) A delegate is a class that, when instantiated, takes a reference method as a parameter to its construction method.
Imagine a scenario where, during a point-to-point file transfer, we design a file transfer class that satisfies at least several of the following features:
- Transmission problem pieces;
- According to percentile notification transmission progress;
- The transport class can be used by both the console program and the WinForm application.
Since the notification itself can be used by the console program and the Winfrom application, the design of this file transfer class cannot display the call when it is making progress notifications:
Console.WriteLine ("Current Progress:" +fileprogress);
Or
This.progressText.Text = "Current progress:" + fileprogress;
Ideally, where notification is required, all of it is replaced by a pointer to a method, and the caller decides what function the method accomplishes. This method pointer is a delegate in C #. You can declare a delegate as follows:
Public Delegate void Fileuploadedhandler (int progress);
This file transfer class can be written like this:
classFileuploader { Public Delegate voidFileuploadedhandler (intprogress); PublicFileuploadedhandler fileuploaded; Public voidUpload () {intFileprogress = -; while(Fileprogress >0) { //transfer code, omitfileprogress--; if(fileuploaded! =NULL) {fileuploaded (fileprogress); } } } }
When invoking this file transfer class, the caller should assign a value to the fileuploaded at the same time, assigning the same declaration method as the delegate declaration to fileuploaded. Thus, the type Fileuploader executes the caller's own method when executing to the following code
Fileuploaded (fileprogress);
After understanding the "delegate is a method pointer", after the understanding that the "delegate is a class".
Look at the following sentence:
Public Delegate void Fileuploadedhandler (int progress);
Its IL code is:
. Class Auto ANSISealednested PublicFileuploadedhandlerextends[mscorlib]system.multicastdelegate{. Method Public Hidebysig specialname rtspecialname instance void. ctor (Object 'Object',nativeInt'Method') Runtimemanaged { } . Method Public HidebysigNewSlotVirtual instance class[mscorlib] System.IAsyncResult BeginInvoke (Int32Progressclass[mscorlib] System.AsyncCallback Callback,Object 'Object') Runtimemanaged { } . Method Public HidebysigNewSlotVirtual instance voidEndInvoke (class[mscorlib] System.IAsyncResult result) Runtimemanaged { } . Method Public HidebysigNewSlotVirtual instance voidInvoke (Int32Progress) Runtimemanaged { }}
To invoke a delegate method:
Fileuploaded (fileprogress);
is actually called:
Fileuploaded.invok (fileprogress);
You can view the IL code for the upload method:
. Method Public Hidebysig instance voidUpload ()CIL managed{ . Maxstack 2 . Locals Init ( [0]Int32fileprogress, [1]BOOLcs$4$0000) l_0000: NOP l_0001: Ldc.i4.s - l_0003: stloc.0 l_0004: BR.Sl_0028l_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 classMytest.fileuploader/fileuploadedhandler mytest.fileuploader::fileuploadedl_0011: ldnull l_0012:ceql_0014: stloc.1 l_0015: Ldloc.1 l_0016: BRTRUE.Sl_0027l_0018: NOP l_0019: ldarg.0 l_001a: ldfld classMytest.fileuploader/fileuploadedhandler mytest.fileuploader::fileuploadedl_001f: ldloc.0 l_0020: callvirt instance voidMytest.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.Sl_0006l_0030: ret }
You can see the Invoke method called at l_0020 .
Bottom line: A delegate is a data type that is used to pass methods.
Turn from: 157 recommendations for writing high-quality code to improve C # programs Minjia
157 recommendations for writing high-quality code to improve C # programs--Recommendation 39: Understanding the nature of a delegate