失誤描述:
我遇到的是這樣的情況,自定義類,然后定義此類的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,以上。