从列表框中将项目集转换为通用列表

46

我希望能够找到一种更好的方法,从checkedlistbox中填充一个通用列表(generic list)在c#中。

我可以很容易地执行以下操作:

List<string> selectedFields = new List<string>();

foreach (object a in chkDFMFieldList.CheckedItems) {
         selectedFields.Add(a.ToString());
         } 

有一个更加优雅的方法可以将CheckedItems集合转换为我的列表。

3个回答

70

试试这个(使用 System.Linq):

OfType() 是一个扩展方法,因此需要使用 System.Linq

List<string> selectedFields = new List<string>();
selectedFields.AddRange(chkDFMFieldList.CheckedItems.OfType<string>());

或者只需在一行中完成:

List<string> selectedFields = chkDFMFieldList.CheckedItems.OfType<string>().ToList();

1
有没有一种方法可以知道ItemCollection的类型?这样该方法就可以使用任何ItemCollection而无需知道类型。 - Carlos Blanco
"OfType<string>()" -- 今天我学到了新东西!谢谢Matt! - Joe Gayetty

17
这并不完全是你所需的答案,但我会提供一个更通用的解决方案。你可以通过以下几种方式来实现:

1)

T[] items = new T[lb.Items.Count];
lb.Items.CopyTo(items, 0);
var lst = new List<T>(items);

2) 使用你提到的 foreach 循环和加法。

3) 使用 Linq。

var lst = lb.Items.Cast<T>().ToList();

4) 或者

var lst = lb.Items.OfType<T>().ToList();

当我进行以下性能测试时,我发现将数据复制到数组的方法最快,而Linq方法较慢。当然,在实际情况下这些差异并不重要。我更喜欢第三种方法(Linq)因为它更易读。

DateTime d = DateTime.Now;
for (int i = 0; i < 10000; i++)
{
    Action();
}
MessageBox.Show((DateTime.Now - d).TotalMilliseconds.ToString());

针对一个包含大约300个项目的列表框进行10000次迭代运行,结果如下:

1) ~100毫秒

2) ~150毫秒

3) ~250毫秒

4) ~260毫秒


3
在深入 StackOverflow 的广阔存档时... @nawfal,解决方案 4)的优点在于,如果您的集合中有不同类型的项(例如,包含 MenuItemSeparator 的菜单),OfType<T> 将只选择集合中的 <T> 项,而解决方案 3) 则会抛出 InvalidCastException - Mike

1

如果您没有访问LINQ,则没有更优雅的方式,因为您要对列表项执行第二个操作(调用ToString()),并且要填充selectedFields集合。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接