将自定义对象添加到 C# 中的选中列表框
Adding custom objects to checked list boxes in C#
我有一个对象,它存储两个字符串并将 ToString() 方法覆盖到 return 这些字符串之一
fooBar temp;
foreach (string foo in bar)
{
temp = new fooBar(); <--- Why is this line needed when I
am overwriting the code and path on each cycle before adding?
temp.code += ".";
temp.path += ".";
Console.WriteLine(temp);
clbFooBar.Items.Add(temp);
}
控制台的打印遵循覆盖的代码和路径字符串值,但选中的列表框项完全相同(最后一项的 ToString()),正在进行的底层进程不是立即显而易见?
如果我将其更改为 clbFooBar.Items.Add(temp.ToString());
它绝对可以正常工作,但那不会与 temp.ToString.ToString()
相同,因为 .Add
首先调用 .ToString()
?我认为控制台打印和 .Add
的行为相同,因为它们都调用 ToString()
编辑:temp = new fooBar();
是我的问题的解决方法,我只是想知道为什么这是解决方法,直觉让我认为覆盖两个字符串、代码和路径就足够了,为什么如果没有重新初始化,选中列表框中的所有项目都是相同的。
您正在 foreach
循环之外创建 temp
,然后在内部对其进行初始化。
如果您不在每次循环时都重新初始化,您最终会得到一个 CheckedListBox
,其中所有项目都指向同一个对象。
这就是为什么您在查看列表时会得到最后一个对象的值(因为实际上只有一个)。
我猜你真正想做的是将 bar 中的每个项目 (foo) 添加到 CheckedListBox
。如果是这样就用这个。
foreach (string foo in bar)
{
foo.code += ".";
foo.path += ".";
Console.WriteLine(foo);
clbFooBar.Items.Add(foo);
}
所以你的问题似乎是,如果你保留这条线,为什么你的代码可以正常工作
temp = new fooBar();
在你的循环中,但如果你忽略这一行,确实会用所有相同的项目填充你的 CheckedListBox
。
原因是如果你在循环外创建只有一个实例fooBar
:
fooBar temp; = new fooBar();
foreach (string foo in bar)
{
temp.code += ".";
temp.path += ".";
clbFooBar.Items.Add(temp);
}
然后您多次添加同一个实例,并且在每次迭代中更改该实例的属性。
如果您像这样在循环中创建新实例:
foreach (string foo in bar)
{
fooBar temp; = new fooBar();
temp.code += ".";
temp.path += ".";
clbFooBar.Items.Add(temp);
}
你每次迭代都有一个新实例,不要更改已经添加的实例。
更新:刚刚注意到,当您将它们全部设置为任何默认值 code
和 temp
时,它们仍然看起来都一样,并加上一个 "."
。因此,您实际尝试做什么仍然有点不清楚。也许是这样的:
string s = string.Empty;
foreach (string foo in bar)
{
s += ".";
fooBar temp; = new fooBar();
temp.code = s;
temp.path = s;
clbFooBar.Items.Add(temp);
}
我有一个对象,它存储两个字符串并将 ToString() 方法覆盖到 return 这些字符串之一
fooBar temp;
foreach (string foo in bar)
{
temp = new fooBar(); <--- Why is this line needed when I
am overwriting the code and path on each cycle before adding?
temp.code += ".";
temp.path += ".";
Console.WriteLine(temp);
clbFooBar.Items.Add(temp);
}
控制台的打印遵循覆盖的代码和路径字符串值,但选中的列表框项完全相同(最后一项的 ToString()),正在进行的底层进程不是立即显而易见?
如果我将其更改为 clbFooBar.Items.Add(temp.ToString());
它绝对可以正常工作,但那不会与 temp.ToString.ToString()
相同,因为 .Add
首先调用 .ToString()
?我认为控制台打印和 .Add
的行为相同,因为它们都调用 ToString()
编辑:temp = new fooBar();
是我的问题的解决方法,我只是想知道为什么这是解决方法,直觉让我认为覆盖两个字符串、代码和路径就足够了,为什么如果没有重新初始化,选中列表框中的所有项目都是相同的。
您正在 foreach
循环之外创建 temp
,然后在内部对其进行初始化。
如果您不在每次循环时都重新初始化,您最终会得到一个 CheckedListBox
,其中所有项目都指向同一个对象。
这就是为什么您在查看列表时会得到最后一个对象的值(因为实际上只有一个)。
我猜你真正想做的是将 bar 中的每个项目 (foo) 添加到 CheckedListBox
。如果是这样就用这个。
foreach (string foo in bar)
{
foo.code += ".";
foo.path += ".";
Console.WriteLine(foo);
clbFooBar.Items.Add(foo);
}
所以你的问题似乎是,如果你保留这条线,为什么你的代码可以正常工作
temp = new fooBar();
在你的循环中,但如果你忽略这一行,确实会用所有相同的项目填充你的 CheckedListBox
。
原因是如果你在循环外创建只有一个实例fooBar
:
fooBar temp; = new fooBar();
foreach (string foo in bar)
{
temp.code += ".";
temp.path += ".";
clbFooBar.Items.Add(temp);
}
然后您多次添加同一个实例,并且在每次迭代中更改该实例的属性。
如果您像这样在循环中创建新实例:
foreach (string foo in bar)
{
fooBar temp; = new fooBar();
temp.code += ".";
temp.path += ".";
clbFooBar.Items.Add(temp);
}
你每次迭代都有一个新实例,不要更改已经添加的实例。
更新:刚刚注意到,当您将它们全部设置为任何默认值 code
和 temp
时,它们仍然看起来都一样,并加上一个 "."
。因此,您实际尝试做什么仍然有点不清楚。也许是这样的:
string s = string.Empty;
foreach (string foo in bar)
{
s += ".";
fooBar temp; = new fooBar();
temp.code = s;
temp.path = s;
clbFooBar.Items.Add(temp);
}