Anonymous Method in Invoke Call

Anonymous method in Invoke call

Because Invoke/BeginInvoke accepts Delegate (rather than a typed delegate), you need to tell the compiler what type of delegate to create ; MethodInvoker (2.0) or Action (3.5) are common choices (note they have the same signature); like so:

control.Invoke((MethodInvoker) delegate {this.Text = "Hi";});

If you need to pass in parameters, then "captured variables" are the way:

string message = "Hi";
control.Invoke((MethodInvoker) delegate {this.Text = message;});

(caveat: you need to be a bit cautious if using captures async, but sync is fine - i.e. the above is fine)

Another option is to write an extension method:

public static void Invoke(this Control control, Action action)
{
control.Invoke((Delegate)action);
}

then:

this.Invoke(delegate { this.Text = "hi"; });
// or since we are using C# 3.0
this.Invoke(() => { this.Text = "hi"; });

You can of course do the same with BeginInvoke:

public static void BeginInvoke(this Control control, Action action)
{
control.BeginInvoke((Delegate)action);
}

If you can't use C# 3.0, you could do the same with a regular instance method, presumably in a Form base-class.

Passing an anonymous method into ProgressBar.Invoke()

That method takes a Delegate, not an Action. Therefore, when you do just this:

() => { .. }

It doesn't know what delegate you want. Do this instead:

progressBar.Invoke(new Action(() => progressBar.Value = count));

C#, invoke anonymous method (Action) from background thread

The syntax would be:

Invoke(action, "long1");

The delegate is the first parameter, and the argument(s) you want to pass to it follow.

Invoking an anonymous method

Just to conclude and close the topic. Based on the comments, both the examples of Invoke calls are correct, but the one using MethodInvoker instantiation is faster, because no extra typecasting has to be performed at runtime, as MrPaulch stated.

Invoking a method of an anonymous class

Can somebody point me to the part of the specification that addresses this?

This will mostly be defined in the section concerning Method invocation expressions:

The first step in processing a method invocation at compile time is to
figure out the name of the method to be invoked and which class or
interface to search for definitions of methods of that name.

For the class or interface to search, there are six cases to consider,
depending on the form that precedes the left parenthesis of the
MethodInvocation:

  • [...]
  • If the form is Primary . [TypeArguments] Identifier, then let T be
    the type of the Primary expression. The class or interface to search
    is T if T is a class or interface type, or the upper bound of T if T
    is a type variable.

Here, the Primary expression is the class instance creation expression. So the type to search is the anonymous type.

Am I right in thinking that the only way you can invoke hello is
immediately like this. What about reflection?

As long as an expression evaluates to the anonymous type T, whether through direct access like you have, or through generics, you have access (regular access rules apply) to the members that T declares. This isn't limited to methods. You can access fields or types, though it's not as useful for types. For example,

Object var = new Object() {
class Nested {
}
}.new Nested();

Since there's no way to refer to the nested type without the enclosing type, you can't declare a variable of that nested type. The usefulness declines very quickly. (Presumably, that's also why you can't have a static nested type within this anonymous class.)

Reflection also exposes this method. The generated anonymous class contains this method, so you can retrieve it and invoke it. The process is the same. The fact that the instance is from an anonymous class doesn't matter. The same strategy as presented in How do I invoke a Java method when given the method name as a string? applies.

For example,

Object ref = new Object() {
public void method() {
System.out.println("hidden");
}
};
Class<?> anonymousClass = ref.getClass();
Method method = anonymousClass.getMethod("method");
method.invoke(ref, new Object[0]);

Don't ever write code like this.

Anonymous method as parameter to BeginInvoke?

Try this:

control.BeginInvoke((MethodInvoker) delegate { /* method details */ });

Or:

private void ConfigureMainMenu(DIServer server)
{
if (control.InvokeRequired)
{
control.BeginInvoke(new Action<DIServer >(ConfigureMainMenu), server);
}
else
{
/* do work */
}
}

Or:

private void ConfigureMainMenu(DIServer server)
{
MenuStrip mnMnu = PresenterView.MainMenu;
if (mnMnu.InvokeRequired)
{
// Private variable
_methodInvoker = new MethodInvoker((Action)(() => ConfigureMainMenu(server)));
_methodInvoker.BeginInvoke(new AsyncCallback(ProcessEnded), null); // Call _methodInvoker.EndInvoke in ProcessEnded
}
else
{
/* do work */
}
}

Cleaner way than Invoke anonymous method in c#

You don't have to wrap your code in a delegate - as long as every case, including the default, assign an explicitly-typed variable, this code will work correctly:

DateTime example;
switch (anotherVariable)
{
case "Jesus birth": example = new DateTime(0, 12, 24); break;
case "Second condition": example = new DateTime(2017, 23, 11); break;
// etc
default: example = DateTime.Now; break;
}

If you insist on using a delegate, you don't need to call Invoke, because you know the type of the delegate. You can use the simple invocation syntax:

var example= (() => {
switch (anotherVariable) {
case "Jesus birth": return new DateTime(0,12,24); break;
case "Second condition": return new DateTime(2017,23,11); break;
//another cases
default: return DateTime.Now; break;
}
}) ();
// ^^
// Invocation

Anonymous method in static class is non-static? How to invoke it?

Bear in mind that this (lambdas) is a compiler feature so the runtime framework version won't make a difference. Also, because this is a compiler feature, it's not all that surprising that there's a difference between 2012 and 2015 (when Roslyn was introduced which replaced most of the existing compiler infrastructure).

I cannot give a solid reason for why it would have been specifically changed here (although I know several changes were made to enabled Edit-and-Continue to work in more contexts), but it has never been contractual about how lambdas are implemented.

How can I get such an instance?

Well, lambda is a Delegate, and that's always exposed a Target property which references an instance when the delegate is so bound.

How to call anonymous function in C#?

Yes, but C# is statically-typed, so you need to specify a delegate type.

For example, using the constructor syntax:

var v = new Func<string>(() =>
{
return "some value";
})();

// shorter version
var v = new Func<string>(() => "some value")();

... or the cast syntax, which can get messy with too many parentheses :)

var v = ((Func<string>) (() =>
{
return "some value";
}))();

// shorter version
var v = ((Func<string>)(() => "some value"))();


Related Topics



Leave a reply



Submit