0

I had a problem with WPF events which I managed me to solve. But I'm not sure why my solution works and why the problem existed in the first place.

The following code runs as expected:

void Test () {

    TextBox tbOne = new TextBox();
    TextBox tbTwo = new TextBox();

    tbOne.TextChanged += (sender, e) => Change(sender, e, 1);
    tbTwo.TextChanged += (sender, e) => Change(sender, e, 2);

    tbOne.Text = "asdf";
    tbTwo.Text = "asdf";
}

public void Change (object sender, TextChangedEventArgs e, int i)
{
    MessageBox.Show("Changed " + i);
}

As the two Message Boxes are displayed:
"Changed 1" and "Changed 2"



I would have expected the result of the following code to be the same:

void Test () {

    TextBox tbOne = new TextBox();
    TextBox tbTwo = new TextBox();

    int i = 1;
    tbOne.TextChanged += (sender, e) => Change(sender, e, i);
    i = 2;
    tbTwo.TextChanged += (sender, e) => Change(sender, e, i);

    tbOne.Text = "asdf";
    tbTwo.Text = "asdf";
}

public void Change (object sender, TextChangedEventArgs e, int i)
{
    MessageBox.Show("Changed " + i);
}

But this displays "Changed 2" and "Changed 2"


In my situation (this code is massively simplified) I had to put the integer into a class of its own in order to "remember" it correctly.

void Test () {

    TextBox tbOne = new TextBox();
    TextBox tbTwo = new TextBox();

    int i = 1;
    IntClass icOne = new IntClass(i);
    tbOne.TextChanged += (sender, e) => Change(sender, e, icOne);
    i = 2;
    IntClass icTwo = new IntClass(i);
    tbTwo.TextChanged += (sender, e) => Change(sender, e, icTwo);

    tbOne.Text = "asdf";
    tbTwo.Text = "asdf";
}

public void Change (object sender, TextChangedEventArgs e, IntClass i)
{
    MessageBox.Show("Changed " + i.i);
}

Where the class IntClass is defined by:

public class IntClass {
    public int i;
    public IntClass (int j)
    {
        i = j;
    }
}

And this works correctly giving "Changed 1" and "Changed 2".


My Question is, why does it work with instances of classes and objects which are stored as references (or with the integer typed directly) and not with an int variable?
I understand that an int isn't stored using a reference but by the value itself, but I don't understand why it should make any difference.

Thanks in advance!

J389
  • 23
  • 1
  • 5
  • When the event is raised, var i has the value 2 - as expected – Sir Rufo Dec 14 '17 at 16:04
  • 2
    Since your `Change` method only actually needs an integer, there's no reason to also accept an object you don't need and an argument class that you don't use. If you only need the integer, only accept and use the integer. – Servy Dec 14 '17 at 16:07
  • 2
    (sender, e) => Change(sender, e, i) means that the function will use value of i (==2) at the moment of the event, not at the moment of the handler was added (1 or 2) – Leonid Malyshev Dec 14 '17 at 16:07
  • Thanks! So the arguments of Change(sender, e, i) are evaluated when the event is raised and not when its defined? – J389 Dec 14 '17 at 16:10

0 Answers0