C# 心得 List.Add, 函数添加的到底是什么?记一次莫名其妙的失误!?

失误描述:

我遇到的是这样的情况,自定义类,然后定义此类的List,然后在循环里添加类到 list 中,但是最后我发现结束后再一次循环输出的结果,只有最后一次的list里全是最后一次的内容!翻看 MSDN中List<T>.Add(T) 的内容发现我在循环里一直用同一个temp,导致list中都导向同一个temp,所以都是这最后一次修改的值!而文档中的示例则是: parts.Add(new Part() {PartName="crank arm", PartId=1234}); 使用的是new 的新实例,所以我怀疑是传引用的参数,在使用自己的类的情况下,Add并不是传的示例!


测试:

T 用string型测试

 1 List<string> test_add_func = new List<string>();
 2 string add_content = "";
 3 for(int i=0; i < 3; i++)
 4 {
 5     add_content = i.ToString();
 6     test_add_func.Add(add_content);
 7 }
 8 test_add_func.ForEach(
 9   delegate (string child) { print(child); }
10   );
  • 输出结果是0 1 2

T 用struct型测试

 1 /*已定义*/ struct test_add { public string m_function; };
 2 
 3 List<test_add> test_add_func2 = new List<test_add>();
 4 test_add add_content2 = new test_add { };
 5 add_content2.m_function = "";
 6 for (int i = 0; i < 3; i++)
 7 {
 8     add_content2.m_function = i.ToString();
 9     test_add_func2.Add(add_content2);10 }
11 test_add_func2.ForEach(
12      delegate (test_add child) { print(child.m_function); }
13      );
  • 输出结果也是0 1 2

T 用自己的类测试

/*已定义*/ class test_add { public string m_function; };
List<test_add> test_add_func2 = new List<test_add>();
test_add add_content2 = new test_add { };
add_content2.m_function = "";
for (int i = 0; i < 3; i++)
{
add_content2.m_function = i.ToString();
test_add_func2.Add(add_content2);
}
test_add_func2.ForEach(
delegate (test_add child) { print(child.m_function); }
);
test_add_func2[0].m_function = "change";
print(add_content2.m_function);
print(test_add_func2[1].m_function);
  • 输出结果为:2 2 2 change change

可见,对于自己定义的类用的是传引用参数!所以要想每个list内容独立,应该传实例像这样 test_add_func2.Add(new test_add { m_function = i.ToString() }); ,这样一来add_content2的内容就不会影响List内容了。


总结:

当使用List的Add函数时,int、struct、string等自带的类可以随意使用,不会传引用参数;但是自定义的类,实际上是传的引用,故需要new 来避免传参导致项目出现不好发现的bug,以上。