Не удается использовать Linq с меню навигации ASP.Net

У меня есть следующий фрагмент кода:

        // Iterate through the root menu items in the Items collection.
        foreach (MenuItem item in NavigationMenu.Items)
        {
            if (item.NavigateUrl.ToLower() == ThisPage.ToLower())
            {
                item.Selected = true;
            }
        }

Я бы хотел:

var item = from i in NavigationMenu.Items
           where i.NavigateUrl.ToLower() == ThisPage.ToLower()
           select i;

Затем я могу установить значение Selected для item, но это дает мне ошибку на NavigationMenu.Items.

Ошибка 5. Не удалось найти реализацию шаблона запроса для исходного типа «System.Web.UI.WebControls.MenuItemCollection». "Где" не найдено. Рассмотрите возможность явного указания типа переменной диапазона 'i'.

Когда я комментирую предложение where, я получаю эту ошибку:

Ошибка 22. Не удалось найти реализацию шаблона запроса для исходного типа «System.Web.UI.WebControls.MenuItemCollection». «Выбрать» не найдено. Рассмотрите возможность явного указания типа переменной диапазона 'i'.


person Neil Knight    schedule 05.08.2011    source источник
comment
Для справки в будущем стоит действительно прочитать сообщение об ошибке - в нем дается точно такой же совет, как и у меня: явное указание типа переменной диапазона.   -  person Jon Skeet    schedule 05.08.2011
comment
Это сообщение появляется, когда я закомментировал часть where оператора Linq. Это дало мне другую ошибку, когда я раскомментировал оператор where.   -  person Neil Knight    schedule 05.08.2011
comment
@Neil: И что это было за это сообщение об ошибке? В общем, на сайтах вопросов и ответов, подобных этому, никогда не рекомендуется говорить, что это дало мне ошибку, не указывая само сообщение об ошибке.   -  person Jon Skeet    schedule 05.08.2011
comment
@Neil: Это не совсем другое сообщение об ошибке — оно по-прежнему говорит вам, что именно вам нужно сделать, чтобы исправить это :)   -  person Jon Skeet    schedule 05.08.2011


Ответы (1)


Я подозреваю, что NavigationMenu.Items реализует только IEnumerable, а не IEnumerable<T>. Чтобы исправить это, вы, вероятно, захотите вызвать Cast, что можно сделать, явно указав тип элемента в запросе:

var item = from MenuItem i in NavigationMenu.Items
           where i.NavigateUrl.ToLower() == ThisPage.ToLower()
           select i;

Однако имя вашего запроса вводит в заблуждение — это последовательность вещей, а не отдельный элемент.

Я бы также предложил использовать StringComparison для сравнения строк, а не верхний регистр их. Например:

var items = from MenuItem i in NavigationMenu.Items
            where i.NavigateUrl.Equals(ThisPage, 
                                 StringComparison.CurrentCultureIgnoreCase)
            select i;

Затем я бы подумал об использовании методов расширения:

var items = NavigationMenu.Items.Cast<MenuItem>()
            .Where(item => item.NavigateUrl.Equals(ThisPage, 
                                 StringComparison.CurrentCultureIgnoreCase));
person Jon Skeet    schedule 05.08.2011
comment
Ох... классный трюк! Хотел бы я знать о Cast раньше. - person Tim; 05.08.2011