1

为什么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);
            }
        }
    }
}
4

4 回答 4

4

您已添加相同的项目aFoo, 5 次。当您修改引用类型对象的内容时,您不会创建新副本,而是修改了同一个对象。

于 2013-03-19T21:33:28.700 回答
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。

于 2013-03-19T21:32:49.453 回答
0

您的变量 'aFoo' 基本上是指向内存中某个位置的指针。如果不“更新”另一个实例(malloc),您将修改内存中的相同位置并添加相同的指针 5 次。

就程序员而言,“new”关键字在 C# 中完成了函数,就像 malloc 在 C 中所做的那样。它将获得一个新的内存位置并使 aFoo 指向该位置,而不是旧的。

来自 MSDN:

The new operator is used to create objects and invoke constructors

MSDN

于 2013-03-19T21:44:08.160 回答
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();

输出:

使用 FooList
0
11
222
3333
44444

使用 foos
01234
于 2013-03-19T21:45:12.530 回答