4

嗨,我有一个关于如何列出的问题。

我正在尝试定义一个列表

List<periodrecord> pl=new List<periodrecord>(4);

然后我希望通过 for 循环将项目添加到列表中

当我这样做时:

for (i = 1; i < 100; i++)
        {
            try
            {
                periodrecord pr = new periodrecord();

                /*some random lines*/

                pl.Add(pr);


            }
            catch (Exception e)
            {  break; }
        }

我的问题是:在每个循环中声明的 pr 的地址将由列表存储。但是由于 pr 变量本身不再被程序使用,这些位置是否会被视为空并以某种方式被覆盖?谢谢。

考虑到答案,还是有些疑惑,我的完整代码如下:

   List<periodrecord> pl=new List<periodrecord>(4);
   for (i = 1; i < 100; i++)
        {
            try
            {
                periodrecord pr = new periodrecord();
                record2 = sr.ReadLine();

                SNorPartCode = record1.Split('&')[0];
                phototype = int.Parse(record1.Split('&')[1]);
                System.Globalization.CultureInfo provider = System.Globalization.CultureInfo.InvariantCulture;
                time = record1.Split('&')[2];
                pr.start = DateTime.Parse(time,provider);
                pr.SNorPartCode = SNorPartCode;
                pr.phototype = phototype;
                if (record2 != null)
                {
                    pr.end = DateTime.Parse(record2.Split('&')[2], provider);
                }
                else
                {
                    pr.end = DateTime.MaxValue;

                }
                pl.Add(pr);
                record1 = record2;

            }
            catch (Exception e)
            {  break; }
        }   

当我下线时: periodrecord pr = new periodrecord();

从 for 循环中出来,行

pr.start=...
pr.end=....

更改了列表中的所有项目。

4

2 回答 2

16

在每个循环中声明的 pr 的地址将由列表存储。

不,不会的。被调用点的变量值存储在列表中。该值是一个引用 - 对您创建的新对象的引用。prAdd

重要的是要了解 C# 中变量的值永远不是对象。它始终是值类型值或引用。一旦你明白了这一点 - 并开始非常清楚变量、它们的值、引用和对象之间的差异 - 很多事情(参数传递、赋值、垃圾收集等)都会变得更加清晰。

例如,考虑:

Button x = new Button();
Button y = x;

这里只有一个对象- 在Button第一行创建的。有两个变量(xy),在第二行之后,由于赋值,它们都具有相同的值(对该对象的引用)。尽管它们仍然是自变量(分配一个新值x不会改变y)。考虑一下如何将其应用于您的示例 - 您正在调用pl.Add(pr)它只是将传递prAdd方法。之后,就列表而言,pr变量完全无关紧要。所以你可以有:

pl.Add(pr);
pr = null;

第二行根本不会影响列表。

于 2013-08-02T06:11:08.763 回答
3

上面的答案很好(当然,由 Jon Skeet - 我无法与之竞争)。但在我看来,您的基本问题是关于如何在 C# 中管理内存。内存在 C# 中是自动管理的,垃圾收集器会在对象超出范围后的某个时间自动释放对对象的引用 - 即在对象的每次 for 循环迭代中pr。但是,垃圾收集器仍然知道该引用仍在列表中使用,因此它永远不会释放该引用,直到列表本身超出范围之后的某个时间。

关于更新的问题:当 pr 在循环内时,您正在将 pr 的值添加到列表中,该值是对该对象的引用。每次你点击循环时,当你创建一个新对象时,这将是一个不同的引用。但是,当 pr 在循环之外时,每次添加到列表中时,都会将 pr 的值(这是参考)添加到列表中,只有这一次无论迭代如何,该值都是相同的。因此,现在列表中的每个项目都包含对同一对象的引用,并且每个项目都将反映对该引用的任何更改。如果您更改索引 5、17、97 或列表中任何其他索引处的项目,则所有项目以及 pr 本身都将被修改,因为所有这些的值都是相同的对象引用。

于 2013-08-02T06:17:49.170 回答