RJP
RJP

Reputation: 4116

Why does one of my values change?

So I have this;

var emailA = ConstructEmailA();
SnedEmailA(emailA.Append("</body>").ToString());

var emailB = ConstructEmailB(emailA);
SendEmailB(emailB.ToString());

Which works fine. Essentially, ConstructEmailB takes emailA and adds to it. However, I originally had this:

var emailA = ConstructEmailA();
var emailB = ConstructEmailB(emailA);
SnedEmailA(emailA.Append("</body>").ToString());                
SendEmailB(emailB.ToString());

Which did not work as expected. Instead of emailA and emailB being different, emailA contained the same info as emailB. How come?

Here is my ConstructEmailB method:

private StringBuilder ConstructEmailB(StringBuilder email)
{
    email.Append("Append stuff");

    return email;
}

Upvotes: 0

Views: 76

Answers (2)

Ed Swangren
Ed Swangren

Reputation: 124790

Which did not work as expected. Instead of emailA and emailB being different, emailA contained the same info as emailB. How come?

Because emailA is emailB. They are both references to the same StringBuilder object, the only difference being when you call SendEmail. In the first case you

  1. construct emailA.
  2. Append to emailA.
  3. Capture the value at that point in time and send it to SendEmailA.
  4. "Construct emailB, which is really just appending to emailA and then send that.

In case 2 you have:

  1. Construct emailA and emailB. They are identical because they are both references to the same StringBuilder.
  2. Append ' to emailA (and thus, also to emailB) and send it.
  3. Send emailB.

Upvotes: 4

Jon Skeet
Jon Skeet

Reputation: 1503779

(Going through the second scenario, the one you don't understand.)

You're only creating a single StringBuilder object. You're passing a reference to that object into ConstructEmailB, which is modifying the contents of that object, and returning the same reference back again.

So you end up with one StringBuilder after the call to ConstructEmailB, with "Append stuff" at the end. You're then appending to that StringBuilder, and calling ToString() on it twice. That will give the same result twice.

I suspect these two articles I wrote a while ago may help you understand:

I'd like to emphasize that it's absolutely critical that you understand what's going on here. While there are various ways of working round it, don't change your code at all (other than for experimentation) until you're sure you understand what's going on.

Upvotes: 2

Related Questions