Click here to Skip to main content
15,907,905 members
Home / Discussions / C#
   

C#

 
AnswerRe: C# Help Pin
Lea Hayes15-Oct-08 11:31
Lea Hayes15-Oct-08 11:31 
QuestionDelegates are trying to make me look stupid Pin
Rob Philpott15-Oct-08 4:17
Rob Philpott15-Oct-08 4:17 
AnswerRe: Delegates are trying to make me look stupid Pin
Ennis Ray Lynch, Jr.15-Oct-08 5:35
Ennis Ray Lynch, Jr.15-Oct-08 5:35 
GeneralRe: Delegates are trying to make me look stupid Pin
Rob Philpott15-Oct-08 5:37
Rob Philpott15-Oct-08 5:37 
GeneralRe: Delegates are trying to make me look stupid Pin
Ennis Ray Lynch, Jr.15-Oct-08 6:14
Ennis Ray Lynch, Jr.15-Oct-08 6:14 
AnswerRe: Delegates are trying to make me look stupid Pin
Le centriste15-Oct-08 6:25
Le centriste15-Oct-08 6:25 
GeneralRe: Delegates are trying to make me look stupid Pin
Rob Philpott16-Oct-08 1:37
Rob Philpott16-Oct-08 1:37 
AnswerRe: Delegates are trying to make me look stupid Pin
Simon P Stevens15-Oct-08 23:32
Simon P Stevens15-Oct-08 23:32 
This puzzled me, so I decided to do some digging to figure out what was happening. Just to warn you thought, I still haven't got a clue what is going on, but I thought I'd share what I looked at with you, maybe you'll spot something I missed.

First thing I tried was looking at the compiled assemblies in reflector.

B:
    ThingDelegate del = new ThingDelegate(this.Thing);
    del();

C:
    new ThingDelegate(this.Thing).BeginInvoke(null, null);


As you can see, they are slightly different. In both cases, the delegate assignment is expanded to use the constructor. (Obviously, the assignment you are doing is just short hand for calling the constructor). What's odd though is that with B, the variable 'del' is kept, but with C, the compiler removes the variable and just calls BeginInvoke directly after creating the delegate. This could just be an artefact of the way reflector rebuilds the code though, we'll have to look at the IL to see.

You can also notice that in both cases, your reference to base.Thing is changed to this.Thing. Which I find a bit strange. To me, this implies that both calls should behave like C, and go into infinite recursion.

Next I took a look with ILDasm
B:
  IL_000c:  ldarg.0
  IL_000d:  ldftn      instance void Confusion.A::Thing()
  IL_0013:  newobj     instance void Confusion.ThingDelegate::.ctor(object,
                                                                    native int)
  IL_0018:  stloc.0
  IL_0019:  ldloc.0
  IL_001a:  callvirt   instance void Confusion.ThingDelegate::Invoke()
  IL_001f:  nop
  IL_0020:  ret

C:
  IL_000c:  ldarg.0
  IL_000d:  ldftn      instance void Confusion.A::Thing()
  IL_0013:  newobj     instance void Confusion.ThingDelegate::.ctor(object,
                                                                    native int)
  IL_0018:  stloc.0
  IL_0019:  ldloc.0
  IL_001a:  ldnull
  IL_001b:  ldnull
  IL_001c:  callvirt   instance class [mscorlib]System.IAsyncResult 
Confusion.ThingDelegate::BeginInvoke(class 
mscorlib]System.AsyncCallback, object)

  IL_0021:  pop
  IL_0022:  ret


Ok, so what's the difference here. The both start with ldarg.0 instruction. This basically pushes the "this" pointer for the current object onto the stack. Then they both do a ldftn which pushes an unmanaged pointer to the method A.Thing() onto the stack (as a native int).

Next they both call the delegate constructor. Which uses the 'this' pointer and A.Thing() pointers that we just pushed (The object and the native int in the brackets)

The next two lines (stloc.0 and ldloc0) basically pop the newly created ThingDelegate off of the stack an into storage index 0, then back onto the stack again ready to be used.

C then has 2 calls to ldnull which simply loads a null pointer onto the stack (for you two null passes to BeginInvoke).

The next line (callvirt) is the call to either Invoke or BeginInvoke. As you can see, we've created the ThingDelegate exactly the same way, and the calls are exactly the same.

finally, C has a pop command to get the IAsyncResult return object off of the stack (and B just does a no-operation), then both return nothing (ret).

Ok, so what's the difference? Nothing as far as I can tell.

Both have been compiled in exactly the same way. Both have created the ThingDelegate using a pointer to this and the A.Thing() method.

The only difference is that one calls Invoke and the other calls BeginInvoke.

My next step was to look at the ThingDelegate itself. In reflector you can see that it extends from System.MulticastDelegate. Basically it declares virtual methods BeginInvoke, EndInvoke and Invoke. You can see exactly the same if you look at the IL.

So where does this leave us? I'm still confused. It seems that the runtime handles the Invoke and BeginInvoke calls. I've used reflector on the MulticastDelegate type and it doesn't even have Invoke or BeginInvoke methods, they are only defined in the ThingDelegate type. I would assume that somehow the call is ultimately directed to the DynamicInvoke method on the base Delegate type, but I've no idea how that happens, or why it's different for the two types of invoke.

I'm totally confused by this. If you ever work it out, please let me know. Smile | :)

Good luck.

Simon

GeneralRe: Delegates are trying to make me look stupid Pin
Rob Philpott16-Oct-08 1:33
Rob Philpott16-Oct-08 1:33 
Questionis it such a thing LinkedLists in C# ? Pin
nesfrank15-Oct-08 3:38
nesfrank15-Oct-08 3:38 
AnswerRe: is it such a thing LinkedLists in C# ? Pin
Simon P Stevens15-Oct-08 3:45
Simon P Stevens15-Oct-08 3:45 
AnswerRe: is it such a thing LinkedLists in C# ? Pin
Kevin McFarlane15-Oct-08 3:46
Kevin McFarlane15-Oct-08 3:46 
AnswerRe: is it such a thing LinkedLists in C# ? Pin
Giorgi Dalakishvili15-Oct-08 3:46
mentorGiorgi Dalakishvili15-Oct-08 3:46 
GeneralRe: is it such a thing LinkedLists in C# ? Pin
nesfrank15-Oct-08 6:29
nesfrank15-Oct-08 6:29 
GeneralRe: is it such a thing LinkedLists in C# ? Pin
Giorgi Dalakishvili15-Oct-08 6:40
mentorGiorgi Dalakishvili15-Oct-08 6:40 
GeneralRe: is it such a thing LinkedLists in C# ? Pin
nesfrank15-Oct-08 7:51
nesfrank15-Oct-08 7:51 
GeneralRe: is it such a thing LinkedLists in C# ? Pin
Dan Neely15-Oct-08 7:09
Dan Neely15-Oct-08 7:09 
GeneralRe: is it such a thing LinkedLists in C# ? Pin
nesfrank15-Oct-08 7:50
nesfrank15-Oct-08 7:50 
QuestionProblems of losing handle to stdcall-api from C#-DLL Pin
J. Holzer15-Oct-08 3:29
J. Holzer15-Oct-08 3:29 
QuestionEnable/disable buttons in Toolbar Pin
kanchoette15-Oct-08 3:24
kanchoette15-Oct-08 3:24 
AnswerRe: Enable/disable buttons in Toolbar Pin
Giorgi Dalakishvili15-Oct-08 3:29
mentorGiorgi Dalakishvili15-Oct-08 3:29 
QuestionThreads and Form Controls Pin
Programm3r15-Oct-08 2:41
Programm3r15-Oct-08 2:41 
AnswerRe: Threads and Form Controls Pin
Giorgi Dalakishvili15-Oct-08 2:49
mentorGiorgi Dalakishvili15-Oct-08 2:49 
GeneralRe: Threads and Form Controls Pin
Programm3r15-Oct-08 2:58
Programm3r15-Oct-08 2:58 
GeneralRe: Threads and Form Controls Pin
Giorgi Dalakishvili15-Oct-08 3:01
mentorGiorgi Dalakishvili15-Oct-08 3:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.