I am new to C# and trying to understand lambda expressions along with delegates. This is the code I am running:
delegate bool D1();
delegate bool D2(int i);
namespace Console
{
class Program
{
D1 d1;
D2 d2;
public void testMethod(int input)
{
int j = 0;
d1 = () => { j = 10; return j < input; };
d2 = (x) => { return x == j; };
System.Console.WriteLine("j = {0}", j);
bool res = d1();
System.Console.WriteLine("res={0}, j ={1}", res, j);
}
static void Main(string[] args)
{
Program p = new Program();
p.testMethod(10);
System.Console.WriteLine(p.d2(10));
System.Console.ReadKey();
}
}
}
What I don't understand is the invocation of d2 prints true. When d2 was constructed value of j was 0. It was changed only after d1 was invoked later in the testMethod. So how it is printing True ? what am I missing here?
d1 and d2 both refer to the same instance of j. When you set j by calling d1 you're also altering the value of the variable that d2 can see.
If you want them do have different instance of j you'll need to scope the variable:
{
int j = 0;
d1 = () => { j = 10; return j < input; };
}
{
int j = 0;
d2 = (x) => { return x == j; };
}
However, if you're going to do this then you might as well have two different variables, say j1 and j2 instead. This will be more readable.
When you create a delegate, any variable outside its scope that it uses is captured. In this case, the delegates assigned to d1 and d2 both capture the variable j declared inside testMethod(); they don't create copies of j, they capture the actual variable. In this sense, during the lifetime of d1 and d2, j behaves inside them as if it was a global variable (though there is no such thing as a global variable in C#, of course).
If you want those methods to get separate instances of j, you would need to provide each method with a copy of j instead of just using it. For instance:
public void testMethod(int input)
{
int j = 0;
int k = j;
d1 = () => { j = 10; return j < input; };
d2 = (x) => { return x == k; };
System.Console.WriteLine("j = {0}", j);
bool res = d1();
System.Console.WriteLine("res={0}, j ={1}", res, j);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With