17

在快速学习 C# 的同时,我偶然发现了这个 Collection 语法问题。

我将一些我自己的 MyItem 类型的对象添加到列表框 lstData。现在我需要在这个列表框中进行搜索,并考虑使用优雅的 LINQ 表示法,例如:

lstData.Items.Where(x => x.Text == SearchString)

但是列表框的项目没有 .Where(),尽管我确实包含了“使用 System.Linq;” 命名空间。

所以我尝试了:

foreach (MyItem item in (MyItem)lstData.Items)

但这会产生构建错误:无法将类型“System.Windows.Forms.ListBox.ObjectCollection”转换为“MySandbox.frmListboxDemo.MyItem”。

我确实设法写了一些可行的东西:

        for (int i = 0; i < lstData.Items.Count; i++)
        {
            MyItem item = (MyItem)lstData.Items[i];
            if (item.Text == SearchString)
            {
                lstData.SetSelected(i, true);
                break;
            }
        }

和类似的版本:

        var item_enum = lstData.Items.GetEnumerator();
        while (item_enum.MoveNext()) { etc etc... }

结果是 2 行更长,并且没有弄清楚什么可以代替“var”。

我不确定我是否了解如何使用 Collections、ObjectCollections、Enumerators 等,但我渴望学习。特别是如果 .Where() 版本是可能的和/或更好的。


感谢您的所有回答。我最终得到了这个解决方案:

        var item_iter = lstData.Items.Cast<MyItem>()
                          .Where(x => x.Text.Trim().ToLower() == txtItemName.Text);
        foreach (MyItem item in item_iter)
        {
            int i = lstData.Items.IndexOf(item);
            lstData.SetSelected(i, true);
            break;
        }

我不知道这是否真的比“fortran”方式好得多(见上文),但它确实教会了我可以在其他 C# 查询中使用的方法。

4

4 回答 4

18

items 集合不是强类型集合。您可以使用IEnumerable<T>.OfType()orIEnumerable<T>.Cast()扩展方法获取 LINQ 世界的条目,您可以在其中过滤条目:

var filteredItems = lstData.Items.OfType<MyItem>().Where(i => i.Prop == val);

Cast 和 OfType 的区别在于:

  • OfType<T>只会返回可转换为 Type T 的项目
  • Cast<T>当集合中至少有一项不可转换为 T 时,将失败
于 2012-11-26T15:19:13.337 回答
14

尝试使用第Cast<T>一个执行转换为您期望的类型。那是:

lstData.Items.Cast<MyItem>().Where(x => x.Text == SearchString)

于 2012-11-26T15:16:13.680 回答
1

ListBox.ObjectCollectionimplements IEnumerable,但不是 generic IEnumerable<T>,这是大多数 Linq 方法所需要的。

一步IEnumerable<T>解决您的选角问题的一种方法是使用Cast<T>

lstData.Items.Cast<MyItem>().Where(x => x.Text == SearchString)
于 2012-11-26T15:19:28.817 回答
0

尝试从项目中列出一个列表:

(new ListBox()).Items.OfType<ListViewItem>().Where(......); 

可能是因为它最初是用早期版本的 .net 构建的

于 2012-11-26T15:21:04.087 回答