Exploring Delegates

Assembly Code

And finally we can start altering assembly code. If you like remove BeginInvoke and EndInvoke from WildCard declaration. Compile it and run it. It still works fine. Next I think that it would be nice to have WildCard derived straight from System.Delegate and maybe to change second parameter of .ctor from native int to void* so that it is more like examples available from Microsoft.
Change WildCard declaration to look like this:

    .class private auto ansi sealed WildCard
    extends [mscorlib]System.Delegate
    {
        .method public specialname rtspecialname 
        instance void .ctor(object Instance, void * Method) runtime managed

        {
        } // end of method WildCard::.ctor

        .method public virtual instance int32 
        Invoke() runtime managed
        {
        } // end of method WildCard::Invoke

        .method public virtual 
        instance class [mscorlib]System.IAsyncResult 
        BeginInvoke(class [mscorlib]System.AsyncCallback callback,
        object Instance) runtime managed
        {
        } // end of method WildCard::BeginInvoke

        .method public virtual 
        instance int32 EndInvoke(class [mscorlib]System.IAsyncResult result) runtime managed
        {
        } // end of method WildCard::EndInvoke

    } // end of class WildCard


Also change code in Main where you are calling WildCard::.ctor so that your code looks like this:

    .method public hidebysig static void Main() cil managed
    {
        .entrypoint
        // Code size 50 (0x32)
        .maxstack 3
        .locals ([0] int32 c,
        [1] class Worker w,
        [2] class WildCard v)
        IL_0000: ldc.i4.2
        IL_0001: stloc.0
        IL_0002: ldloc.0
        IL_0003: newobj instance void Worker::.ctor(int32)
        IL_0008: stloc.1
        IL_0009: ldloc.1
        IL_000a: ldftn instance int32 Worker::Multiply()
        IL_0010: newobj instance void WildCard::.ctor(object,
                                                                            void *)
        IL_0015: stloc.2
        IL_0016: ldstr "Argument is {1}\nResult is {0}"
        IL_001b: ldloc.2
        IL_001c: callvirt instance int32 WildCard::Invoke()
        IL_0021: box [mscorlib]System.Int32
        IL_0026: ldloc.0
        IL_0027: box [mscorlib]System.Int32
        IL_002c: call void [mscorlib]System.Console::WriteLine(string,
                                                                            object,
                                                                            object)
        IL_0031: ret
    } // end of method User::Main


If you don’t change it that will compile but will generate run time error. Compile it and check using debugger type of WildCard.
If you were reading “C:\Program Files\Microsoft.NET\FrameworkSDK\Tool Developers Guide\docs\Partition II Metadata.doc” there is under 13.6 Delegates following:

    "A better design would be to simply have delegate classes derive directly from System.Delegate." 

I hope that this article shows how that could be done using ILASM.
If you have any question or suggestion I can be reached at [email protected] if time allows I will come back to you.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” - Martin Fowler