Domanda

What exactly is the difference between this two uses of MethodInvoker:

1:

textBox1.Invoke(new MethodInvoker(b));

2:

textBox1.Invoke((MethodInvoker)delegate { b(); });

I only understand, that variant 2 allow me to call b() with parameters if i want. But what is the difference between this 2 versions?

Version 1 is clear to me: I create a new delegate and pass it my b() method, which has the same return-type and paramaters as the MethodInvoker delegate. Standardcase of a delegate.

But what does version 2 exactly? What means/does here the "delegate" keyword?

È stato utile?

Soluzione 2

V1 creates a new MethodInvoker object and passes it your b method as a parameter. What the MethodInvoker then "does with b" is up the the class itself.

In V2 you create a anonymous method and cast it to MethodInvoker and do not instanciate any "additional object" and your delegate is executed "directly". Another even shorter way of calling this using Lambdas:

textBox1.Invoke(() => b()); // or .Invoke((Action)() => b());

In V1 you could also replace MethodInvoker with your own implementation, e.g. a TryCatchLogInvoker which does not execute b directly, but wraps it to logs exceptions happening "inside b".

Altri suggerimenti

I only understand, that variant 2 allow me to call b() with parameters if i want.

No, even with first version you can do it:

textBox1.Invoke(new MethodInvoker(b), parameter1, parameter2);

But what is the difference between this 2 versions?

In second version there is an extra delegate to be called (and its body is just to call b()). There may be use cases for this (for example if you need a closures, see later) but in this case it has no meaning.

But what does version 2 exactly? What means/does here the "delegate" keyword?

It's an anonymous method, if you check at generated code you'll see it's somehow equivalent to this:

void MyAnonymousMethod() {
    b();
}

void b() {
}

...

textBox1.Invoke(new MethodInvoker(MyAnonymousMethod));

As you can see it's pretty useless (in this case) because you add an useless expansive delegate call. It may be useful if you use it to capture variables:

int a = CalculateValueA();
textBox1.Invoke((MethodInvoker)delegate {
    b(a / CalculateValueC(), anotherParameter); 
});

Note that this is pretty different than this:

int a = CalculateValueA();
textBox1.Invoke(new MethodInvoker(b), a / CalculateValueC());

Because of when function will be called and expressions evaluated. To understand all the implications see also MSDN for details about closures in C#. Same code hand-made will be much more complicated to write (you'll need to define your class to hold parameters/function calls). A quick inspection to decompiled code will make this much more clear.

Another common case is when you have to adapt e method prototype. It's not the case for MethodInvoker but you may want to call a method with - let's say - no parameters from an event (with object and EventArgs parameters). In this case you have some options:

  • Create an event handler method with proper prototype then simply invoke the method you want.
  • Create an anonymous delegate (like you did or with a lambda). Don't forget that anonymous delegate can't be simply detached from event handlers...
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top