我有这个代码:
List<List<string>> strs = new List<List<string>>();
List<string> str = new List<string>();
foreach (DataGridViewRow sr in dataGridView1.SelectedRows)
{
if(i >= 10)
{
strs.Add(str); //Here strs have one str with 10 values
str.Clear();
i = 0;
var a = strs; //Here strs have one str with 0 values
}
str.Add(sr.Cells["MOBILNI"].Value.ToString().Trim());
i++;
}
strs.Add(str);
Run Code Online (Sandbox Code Playgroud)
我列出了strings我填充的列表,当它达到10个成员时,我将整个列表放入列表中List<string>,然后清除列表strings以填充下一个10项.问题是,当strings达到10个成员的列表时,我将其添加到列表中List<string>并在调试中我看到我strs有1个成员(List<string>)其中有10个元素(10个字符串)但是当我清除strings它的基本列表时它也清除了里面的列表List<List<string>>.
当我使用str = new List<string>()而不是str.Clear()它正常工作.
那为什么会发生这种情况以及如何克服它?
当您编写时strs.Add(str),将完全相同的实例添加List<string>到您的列表列表中,之后您将其清除.呼叫str.Clear将因此被反射到该实例的所有引用,还strs[0],strs[1]等等.发生这种情况是因为a List<T>是引用类型.使用一个引用执行任何操作都将反映在所有引用中.另一方面,值类型将在将对象传递给方法时复制整个对象.因此,以下代码将在调用后i获得该值.4DoSomething
int i = 4;
var result = DoSomething(i);
void DoSomething(int j)
{
j = -7;
}
Run Code Online (Sandbox Code Playgroud)
为了避免这种情况,你必须创建一个全新的列表,而不是仅仅添加现有的列表:
foreach (DataGridViewRow sr in dataGridView1.SelectedRows)
{
if(i >= 10)
{
strs.Add(new List<string>(str));
str.Clear();
i = 0;
var a = strs; //Here strs have one str with 0 values
}
str.Add(sr.Cells["MOBILNI"].Value.ToString().Trim());
i++;
}
strs.Add(str);
Run Code Online (Sandbox Code Playgroud)