为什么我的一个价值观会发生变化?

时间:2012-03-15 19:26:23

标签: c#

所以我有这个;

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

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

哪个工作正常。从本质上讲,ConstructEmailB需要使用emailA并添加它。但是,我最初有这个:

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

哪个没有按预期工作。 emailA包含与emailB相同的信息,而不是emailA和emailB不同。怎么样?

这是我的ConstructEmailB方法:

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

    return email;
}

2 个答案:

答案 0 :(得分:4)

  

哪个没有按预期工作。 emailA包含与emailB相同的信息,而不是emailA和emailB不同。怎么样?

因为emailA emailB。它们都是对同一个StringBuilder对象的引用,唯一的区别是当调用SendEmail。在第一种情况下你

  1. 构建emailA
  2. 附加到emailA
  3. 在该时间点捕获值并将其发送至SendEmailA
  4. “构建emailB,这只是附加到emailA然后发送。
  5. 在案例2中你有:

    1. 构建emailAemailB。它们是相同的,因为它们都是对同一StringBuilder的引用。
    2. '附加到emailA(以及emailB)并发送给它。
    3. 发送emailB

答案 1 :(得分:2)

(通过第二个场景,你不理解的场景。)

您只创建一个StringBuilder对象。您将对该对象的引用传递给ConstructEmailB,它正在修改该对象的内容,并再次返回相同的引用。

因此,在调用StringBuilder之后,您最终会使用一个 ConstructEmailB,最后添加“附加内容”。然后,您将附加到StringBuilder,并在其上调用ToString()两次。这将两次给出相同的结果。

我怀疑我刚才写的这两篇文章可以帮助你理解:

我想强调一下,绝对批判,你明白这里发生了什么。虽然有各种方法可以解决这个问题,但是在你确定了解正在发生的事情之前,不要改变你的代码(除了实验)。