Lambda with BackgroundWorker
c#, lambda
Solution
Let me clarify lambda's for you:
(a,b) => TestMethod("", "", "");
Translates to:
private void AnonymousLambda(object a, EventArgs b)
{
TestMethod("", "", "");
}
The syntax of a lambda is:
implicit method arguments => method body
The implicit method arguments are determined by the expected signature of what the method is being assigned to (or called from). Because you're assigning this lambda expression to the `DoWorkEventHandler` delegate, it automatically interprets `a` and `b` as `object` and `EventArgs` respectively.
In some cases, the compiler cannot infer the implicit types for the parameters of the lambda, so you could also have written them explicitly:
(object a, EventArgs b) => TestMethod("", "", "");
So you're really calling your TestMethod in the body of another method which you anonymously created! And the outer method has the `DoWorkEventHandler` method signature.
EDIT
Per the additional question details about the string variables, the compiler is creating a closure over your code to include the variables in the scope of the method. The code basically becomes a new class which holds the variables as private fields and then references them in the call:
public class AnonymousClosureClass
{
public void AnonymousLambda(object a, EventArgs b)
{
// Note the reference to the original class instance
String one = originalClassReference.one;
String two = originalClassReference.two;
String three = originalClassReference.three;
TestMethod(one, two, three);
}
}
And your main code effectively becomes:
BackgroundWorker bw = new BackgroundWorker();
// Note: these may become field members to remain visible to the closure class
String one = resultFromSomeMethod();
String two = resultFromOtherMethod();
String three = resultFromThirdMethod();
var closure = new AnonymousClosureClass();
bw.DoWork += closure.AnonymousLambda;
Finally, worth noting, this is not how the actual generated closure code is named or looks, at all.
Problem
Why is the following syntax valid? ``` BackgroundWorker bw = new BackgroundWorker(); String one = resultFromSomeMethod(); String two = resultFromOtherMethod(); String three = resultFromThirdMethod(); bw.DoWork += (a,b) => TestMethod(one, two, three); ``` where TestMethod is defined as: ``` private void TestMethod(String one, String two, String three){ //Do Stuff!! } ``` The `DoWorkEventHandler` is defined as a delegate that takes two parameters: object sender and EventArgs e. However, the TestMethod above takes no such parameters. By my understanding of a delegate, to create a new delegate the method has to conform to the delegate's declaration. I seem to have bypassed that restriction by using a lambda. How and why does the syntax above work, even though if I try to create a `new DoWorkEventHandler(TestMethod)` it most certainly would not work? I read Eric White's blog on Lambda Expressions but it didn't seem to answer this question.