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

Ale*_*lex 37 c# casting listbox list

我想找到一种更好的方法来填充c#中的checkedlistbox中的通用列表.

我可以很容易地做到以下几点:

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

foreach (object a in chkDFMFieldList.CheckedItems) {
         selectedFields.Add(a.ToString());
         } 
Run Code Online (Sandbox Code Playgroud)

必须有一个更精细的方法将CheckedItems集合强制转换为我的列表.

Mat*_*ton 54

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

OfType() 是一种扩展方法,所以你需要使用 System.Linq

List<string> selectedFields = new List<string>();
selectedFields.AddRange(chkDFMFieldList.CheckedItems.OfType<string>());
Run Code Online (Sandbox Code Playgroud)

或者只是在一行中:

List<string> selectedFields = chkDFMFieldList.CheckedItems.OfType<string>().ToList();
Run Code Online (Sandbox Code Playgroud)


naw*_*fal 12

这不是您的要求的答案,而是发布更一般的答案.你可以用各种方式做到这一点:

1)

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

2)foreach如你所述循环和添加使用.

3)使用Linq

var lst = lb.Items.Cast<T>().ToList();
Run Code Online (Sandbox Code Playgroud)

4)或

var lst = lb.Items.OfType<T>().ToList();
Run Code Online (Sandbox Code Playgroud)

当我像下面那样进行一些性能测试时,我发现复制到数组方法最快,而Linq方法更慢.当然,在现实世界的场景中,这些并不重要.我更喜欢第三种方法(Linq)的可读性.

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

对于10000次的迭代,在列表框中运行多次约300项,

1)~100ms

2)~150ms

3)~250ms

4)~260ms

  • 挖掘 StackOverflow 的庞大档案...@nawfal,解决方案 **4)** 的优点是,如果您的集合中有不同的项目(例如带有`MenuItem`s 和`Separator`s ​​的菜单)`OfType&lt; T&gt;` 只会从集合中只选择 `&lt;T&gt;` 项,而 **3)** 会抛出 `InvalidCastException`。 (2认同)