为什么aFooList
包含最后一项的五个副本,而不是我插入的五个项目?
预期输出:01234
实际输出:44444
using System;
using System.Collections.Generic;
namespace myTestConsole {
public class foo {
public int bar;
}
class Program {
static void Main(string[] args) {
foo aFoo = new foo(); // Make a foo
List<foo> aFooList = new List<foo>(); // Make a foo list
for (int i = 0; i<5; i++) {
aFoo.bar = i;
aFooList.Add(aFoo);
}
for (int i = 0; i<5; i++) {
Console.Write(aFooList[i].bar);
}
}
}
}
答案 0 :(得分:4)
您添加了相同的项目aFoo
,共5次。修改引用类型对象的内容时,如果不创建新副本,则修改同一对象。
答案 1 :(得分:2)
List<foo> aFooList = new List<foo>(); // Make a foo list
for (int i = 0; i<5; i++) {
foo aFoo = new foo(); // Make a foo
aFoo.bar = i;
aFooList.Add(aFoo);
}
您仍在修改列表中的aFoo。
答案 2 :(得分:0)
你的变量'aFoo'基本上是指向内存中某个位置的指针。如果没有“新建”另一个实例(malloc),你将在内存中修改相同的位置并添加相同的指针5次。
“new”关键字完全填充函数,就像程序员关注C#中malloc在C中所做的那样。它将获得一个新的内存位置并使aFoo指向该位置,而不是旧位置。
来自MSDN:
The new operator is used to create objects and invoke constructors
答案 3 :(得分:0)
您已将同一对象的引用添加到列表中5次,每次都修改bar
的值。在aFooList.Add(aFoo);
之后添加此行,以便在每次向列表中添加foo
时查看效果。
Console.WriteLine(string.Join("", foos.Select(f => f.bar)));
对于它的价值而言,它与Linq一起使用(可读性很好)。
var foos = Enumerable.Range(0, 5)
.Select(n => new foo {bar = n})
.ToList();
完整示例:
foo aFoo = new foo(); // Make a foo
List<foo> aFooList = new List<foo>(); // Make a foo list
Console.WriteLine("\nUsing aFooList");
for (int i = 0; i < 5; i++)
{
aFoo.bar = i;
aFooList.Add(aFoo);
Console.WriteLine(string.Join("", aFooList.Select(f => f.bar)));
}
var foos = Enumerable.Range(0, 5).Select(n => new foo { bar = n }).ToList();
Console.WriteLine("\nUsing foos");
Console.WriteLine(string.Join("", foos.Select(f => f.bar)));
Console.ReadLine();
输出:
Using aFooList 0 11 222 3333 44444 Using foos 01234