Вопрос по linq, vb.net – В запросе Linq есть неявная ошибка приведения для DataGridViewRow, если включен строгий параметр

1

У меня есть DataGridView, который связан со списком объектов под названием «BaseChange». Объекты BaseChange состоят из 4 свойств ...

  • ChangeType
  • ChangeStatus
  • ChangeDescription
  • LastChangeDate

В сетке данных есть столбцы для всех 4-х значений и 5-го (столбец с флажком «colIsSelected»). Нет проблем с привязкой списка к сетке и отображением элементов.

Проблема в том, что запрос, который выбирает выбранные элементы в сетке, дает мне неявную ошибку приведения, когда включен строгий параметр.

Это запрос ...

Dim _changes As List(Of BaseChange)

_changes = (From _row As DataGridViewRow In dgvChanges.Rows() _
            Where Convert.ToBoolean(_row.Cells(NAME_COLUMN_IS_SELECTED).Value) = True _
            Select DirectCast(_row.DataBoundItem, BaseChange)).ToList()

... и он дает правильные результаты со строгой опцией off. Неявное приведение в порядок приведено к тегу _row As DataGridViewRow. код и полное сообщение & quot;Implicit conversion from 'Object' to 'System.Windows.Forms.DataGridViewRow'& Quot ;.

Если я исключу & quot; Как DataGridViewRow & quot; из запроса я получаю ошибку позднего связывания для _row.Cells и _row.DataBoundItem, и это также не соответствует строгому параметру.

Мне это нужно для работы с включенным Option Strict и в VB. Я что-то здесь упускаю? У кого-нибудь есть предложения?

Ваш Ответ

1   ответ
3
(From _row As DataGridViewRow In dgvChanges.Rows() 

Ваш тип объекта _row должен соответствовать единственной версии типа коллекции.

как в:

    'Assumes Option Strict On and Option Implicit On
    Dim _changes = (From _row In dgvChanges.Rows() _            
           Where Convert.ToBoolean(ctype(_row,DataGridViewRow).Cells(NAME_COLUMN_IS_SELECTED).Value) = True _           
Select DirectCast(ctype(_row,DataGridViewRow).DataBoundItem, BaseChange)).ToList()

Linq видит вашу коллекцию Rows () как IEnumerable, поэтому ваша строка является объектом. Объяснение внизу уходит в более подробно.

Добавлено:

Добавление опции Infer должно упростить это.

Смотрите для более подробной информации:

Как лучше всего смешивать Option Strict VB.NET и новые директивы Option Infer?

а также

http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/e3ec737a-42f8-4767-a190-78390202a991/

Объяснение: Я еще немного покопался, почему это не проще. RowCollection для DataGridView реализует более старый интерфейс IEnumberable, который возвращает объекты, в то время как более новые типы коллекций реализуют универсальный интерфейс IEnumerable (Of T), который возвращает тип напрямую, устраняя необходимость в приведении.

УвидетьMSDN для реализованных интерфейсов.

Спасибо, это имеет большой смысл. StingyJack
Я добавил & quot; Объяснение & quot; абзац внизу, который объясняет, почему приведение требуется, когда его нет в большинстве примеров кода, которые вы видите.
Я добавил немного текста внизу, в основном, добавить опцию Infer
Это решает проблему, но меня все еще немного смущает, почему коллекция Rows () фактически не рассматривается как коллекция DataGridViewRow. Вы знаете, где я могу получить больше информации об этом? Это для небольшого приложения, но меня беспокоит количество кастинга, которое может понадобиться в более крупном приложении. Мне не приходилось делать это для других (универсальных) типов коллекций, стоит ли ожидать этого при использовании LINQ против неуниверсальных коллекций? Это такой большой удар по производительности, как кажется? StingyJack

Похожие вопросы