Синтаксис коллекции listbox C#
изучая C# довольно быстро, я натыкаюсь на эту проблему синтаксиса коллекции.
я добавил несколько объектов моего собственного типа MyItem в listbox lstData. Теперь мне нужно найти в этом списке и подумать об использовании элегантной нотации LINQ, например:
lstData.Items.Where(x => x.Text == SearchString)
но элементы списка не имеют a .Where (), хотя я включил "использование системы.Linq; " пространство имен.
поэтому я попытался:
foreach (MyItem item in (MyItem)lstData.Items)
но это дает ошибку построения : Нельзя преобразовать тип System.Окна.Формы.список.ObjectCollection 'to' 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".
Я не совсем уверен, что понимаю, как использовать коллекции, ObjectCollections, Перечислители и т. д., Но я хочу учиться. Особенно если .Где() версия возможна и / или лучше.
Спасибо за все ваши ответы. Я закончил с этим решением:
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 ответов
попробуйте использовать Cast<T>
сначала выполните приведение к типу, который вы ожидаете. То есть:
lstData.Items.Cast<MyItem>().Where(x => x.Text == SearchString)
коллекция элементов не является строго типизированной коллекцией. Вы можете использовать IEnumerable<T>.OfType()
или IEnumerable<T>.Cast()
методы расширения, чтобы получить запись в мир LINQ, где вы можете фильтровать ваши записи:
var filteredItems = lstData.Items.OfType<MyItem>().Where(i => i.Prop == val);
разница между Cast и OfType:
-
OfType<T>
просто вернет элементы, которые можно кастовать, чтобы ввести T -
Cast<T>
не будет выполнена, если хотя бы один элемент в коллекции, который не приводим к Т
ListBox.ObjectCollection
осуществляет IEnumerable
, но не универсальный IEnumerable<T>
, что требуется для большинства методов Linq.
один способ добраться до IEnumerable<T>
и решить проблему литья в один шаг, чтобы использовать Cast<T>
:
lstData.Items.Cast<MyItem>().Where(x => x.Text == SearchString)
попробуйте сделать список из элементов:
(new ListBox()).Items.OfType<ListViewItem>().Where(......);
вероятно, причина в том, что он был первоначально построен с более ранней версией .net