您好我有关于如何列出的问题。
我想通过
定义一个列表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=....
更改了列表中的所有项目。
答案 0 :(得分:16)
每个循环中声明的pr的地址将由列表存储。
不,它不会。调用pr
时Add
变量的值将存储在列表中。该值是一个引用 - 对您创建的新对象的引用。
重要的是要理解C#中变量的值是永远一个对象。它始终是值类型值或引用。一旦你了解了它 - 并开始非常清楚变量,它们的值,引用和对象之间的差异 - 很多事情(参数传递,赋值,垃圾收集等)变得更加清晰。
例如,考虑:
Button x = new Button();
Button y = x;
这里只有一个对象 - 在第一行创建的Button
。有两个变量(x
和y
),在第二行之后,由于赋值,它们都具有相同的值(对该对象的引用)。但它们仍然是独立变量(为x
分配新值不会更改y
)。考虑一下如何将其应用于您的示例 - 您正在调用pl.Add(pr)
,它只是将pr
的值传递给Add
方法。之后,就列表而言,pr
变量完全不相关。所以你可以:
pl.Add(pr);
pr = null;
并且第二行根本不会影响列表。
答案 1 :(得分:3)
上面的答案很棒(当然,Jon Skeet - 我无法与之竞争)。但对我来说,你的基本问题就是如何在C#中管理内存。内存为managed automatically in C#,垃圾收集器在它们超出范围后的某个时间自动处理释放对象的引用 - 即在对象pr
的情况下在for循环的每次迭代中。但是,垃圾收集器仍然会知道列表仍在使用该引用,因此它将永远不会在列表本身超出范围之后的某个时间解除分配。
关于更新的问题:当pr在循环内部时,您将向列表中添加pr的值,该值是对该对象的引用。每次进入循环时,在创建新对象时,这将是一个不同的引用。但是,当pr在循环之外时,每次添加到列表中时,您将向列表中添加pr的值(这是引用),只有这一次,无论迭代如何,该值都是相同的。因此,现在列表中的每个项目都包含对同一对象的引用,并且每个项目都将反映对该引用的任何更改。如果更改索引5,或17或97或项目列表中任何其他索引的项目,则将修改所有项目以及pr本身,因为所有这些项目的值都相同对象参考。