堆、栈---ta不经意来了
好吧,写下来做个记念,顺便把他们滴结构在脑袋里留下一道影像。
近日同事让咱看一段java代码问题,其实转为C#后大概就是如下代码:
书类:
class Book
{
string id;
string name;
/// <summary>
/// 书编号
/// </summary>
public string Id
{
set { id = value; }
get { return id; }
}
/// <summary>
/// 书名称
/// </summary>
public string Name
{
set { name = value; }
get { return name; }
}
}
某执行方法体:
List<Book> li = new List<Book>();
Book bk = new Book();
for (int i = 0; i < 3; i++)
{
bk.Id = "Sgvon" + i + "00000";
bk.Name = "《晚风那个吹》第" + (i + 1).ToString() + "部";
li.Add(bk);
}
foreach (Book b in li)
{
Response.Write("书编号:" + b.Id + " 书名:" + b.Name + "<br />");
}
问题看似是一步步执行,先用循环存Book的实例bk到List<Book>中,然后循环取值,然而输出得到的所有结果都是最后一本书。
奇了怪了,几经走访,终于发现了问题的所在······根据堆栈滴分配,类类型是存在堆上滴,这样疑问就终结了。Book属于类类型所以ta的实质是存在堆上滴,而bk只是保存了一个访问ta滴地址,所以咱们在循环取值时,指向Book在堆中的空间,他的属性值当然是最后一次给他赋滴值。理解起来也就是这样:bk就好比一个地址:XX省XX市XX区XX号XX大厦XX室。而Book就是这个具体滴XX室,不管这个XX室不断改变外表滴颜色,我去找他滴时候,当然只能看到他最后一次刷滴颜色。所以在取值时总是得到最后一条记录了。所以最终代码应该是在循环里面构造bk,这样每次循环都在堆上开辟了一方Book居住滴沃土,从而bk滴地址也不同了。
更正后代码应该是:
List<Book> li = new List<Book>();
for (int i = 0; i < 3; i++)
{
Book bk = new Book();
bk.Id = "Sgvon" + i + "00000";
bk.Name = "《晚风那个吹》第" + (i + 1).ToString() + "部";
li.Add(bk);
}
foreach (Book b in li)
{
Response.Write("书编号:" + b.Id + " 书名:" + b.Name + "<br />");
}
各位如云滴牛字辈高手,千万木激动,诸葛亮曾经说过:“冷静,一定要随时保持冷静。” 这个问题虽小,但偶尔遇到还是会杀咱们个措手不及。

浙公网安备 33010602011771号