堆、栈---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 />");
            }

各位如云滴牛字辈高手,千万木激动,诸葛亮曾经说过:“冷静,一定要随时保持冷静。”  这个问题虽小,但偶尔遇到还是会杀咱们个措手不及。

posted @ 2009-10-23 17:56  Sgvon  阅读(67)  评论(0)    收藏  举报