Подтвердить что ты не робот

Var не будет работать с DataGridViewRow

Я новичок в С# и задаю вопрос об использовании "var"

Когда я использую следующий код, все работает отлично

foreach(DataGridViewRow row in myGrid.Rows)
{
    if (row.Cells[2].Value.ToString().Contains("51000"))
    {
        row.Cells[0].Value = "X";
    }
}

Но когда я меняю DataGridViewRow на var, я получаю и ошибка, которая указывает

'object' не содержит определения для "Ячейки" и никакого расширения метод "Ячейки", принимающие первый аргумент типа "объект", может быть (вам не хватает директивы использования или ссылки на сборку?)

4b9b3361

Ответ 1

Это потому, что свойство GridView.Rows возвращает тип GridViewRowCollection.

В этом случае var не может вывести из использования, что объект будет DataGridViewRow внутри.

Источник: Свойство GridView.Rows

Ответ 2

myGrid.Rows имеет тип DataGridViewRowCollection.

Эта вещь довольно старая, ее определение гласит:

public class DataGridViewRowCollection : ICollection, IEnumerable, IList

Вы видите не общие интерфейсы? Этот класс может реализовать IList<DataGridViewRow>, а затем var будет работать, но он устарел.

IEnumerable не передает информацию о типе элемента, а функция GetEnumerator здесь не помогает, поскольку она возвращает IEnumerator, тогда как он может вернуть IEnumerator<DataGridViewRow>.

По сути, компилятор С# ищет функцию GetEnumerator, которая возвращает объект, который имеет функцию MoveNext и свойство Current (или интерфейс IEnumerable<T>/IEnumerable при явной реализации). Этот подход duck-typing относится к историческим причинам, он существовал до того, как дженерики были введены в язык. Переменная цикла foreach будет иметь тот же тип, что и свойство Current. И в IEnumerator (не общий вариант), Current имеет тип object.

Указание типа явно:

foreach (DataGridViewRow row in myGrid.Rows)

просто возвращает возвращаемое значение Current в DataGridViewRow из-за отсутствия лучшего механизма.

Вы также можете использовать LINQ для достижения такого же эффекта, если вы действительно хотите использовать это ключевое слово var здесь:

foreach (var row in myGrid.Rows.Cast<DataGridViewRow>())

Это работает, потому что метод расширения Enumerable.Cast<T> возвращает IEnumerable<T>, который, в свою очередь, использует IEnumerator<T>, а T заканчивается как тип Current перечислителя, поэтому информация типа распространяется.

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

Ответ 3

DataGridViewRow.Rows имеет тип DataGridViewRowCollection, который не реализует IEnumerable<DataGridViewRow>, только IEnumerable. И object - лучшее предположение, которое может сделать компилятор, если вы не укажете приведение в DataGridViewRow для row

Ответ 4

Если вы измените DataGridViewRow на Var С#, не уверены, что существует массив, называемый ячейками. Чтобы исправить это, вы можете использовать var как DataGridViewRow, но почти всегда лучше использовать этот тип, если вы его знаете, ищите в Интернете информацию о типе безопасности, чтобы получить дополнительную информацию.