c # проверить, содержит ли столбец datagridview значение & linq First () vs FirstOrDefault () - PullRequest
0 голосов
/ 01 ноября 2019

Мне нужно проверить, содержит ли первый столбец в DataGridView значение 10

Я использовал это

int index = -1;  
index = (dgv.Rows.Cast<DataGridViewRow>()  
        .Where(r => r.Cells[0].Value.Equals(10))  
        .Select(r => r.Index)).First();  

, но иногда выдает ошибку: последовательность не содержит элементов

Кто-то на этом форуме предложил использовать FirstOrDefault() no First()

Это работает НО, если первый столбец в первой строке содержит значение 10 или нет строк, в которых первый столбец содержит значение 10, переменная index имеет значение 0

Мое решение было:

try {
 index = (dgv.Rows.Cast<DataGridViewRow> ()
  .Where(r => r.Cells[0].Value.Equals(10))
  .Select(r => r.Index)).First();
} catch {
 index = -1
}

С уважением,

Ответы [ 4 ]

2 голосов
/ 01 ноября 2019

Мне нужно проверить, содержит ли первый столбец в DataGridView значение 10

Правильный инструмент (метод) для задания будет .Any, который возвращает true, если какой-либо элемент изколлекция удовлетворяет заданному условию, или false, если нет, или коллекция пуста.

if (dgv.Rows.Cast<DataGridViewRow>().Any(r => r.Cells[0].Value.Equals(10)))
{
    // exists
}  
else
{
    // not exist
}

Если вам действительно нужно значение индекса, используйте метод .DefaultIfEmpty для возврата значения по умолчанию для случая, когда коллекция пуста илитребуемое значение не найдено.

var index = dgv.Rows.Cast<DataGridViewRow>()  
    .Where(r => r.Cells[0].Value.Equals(10))
    .Select(r => r.Index)
    .DefaultIfEmpty(-1)
    .First();

С помощью .DefaultIfEmpty вы можете «сообщить» читателям вашего кода свое действительное намерение без дополнительных условий или нулевых пропагаторов.
И поскольку вы предоставляете значение по умолчанию в случае пустой коллекциивернувшись, вы можете безопасно использовать метод .First(), потому что всегда будет возвращен хотя бы один элемент.

Для поиска всех вхождений данного значения не используйте First или FirstOrDefault.

0 голосов
/ 01 ноября 2019

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

Для решения этой проблемы вы можете использовать ноль объединяется оператор с FirstOrDefault(), как

int index = dgv.Rows.Cast<DataGridViewRow>()
                .FirstOrDefault(r => r.Cells[0].Value.Equals(10))?.Index 
                 ?? -1;  
0 голосов
/ 01 ноября 2019

Альтернатива:

int index; 
var row = dgv.Rows.Cast<DataGridViewRow>().FirstOrDefault(r => r.Cells[0].Value == 10);
if (row != null)
    index = row.Index;
else
    index = -1; // or whatever you want
0 голосов
/ 01 ноября 2019

Как MSDN говорит о First () :

Возвращает первый элемент последовательности. Метод First (IEnumerable) выдает исключение, если источник не содержит элементов. Чтобы вместо этого возвратить значение по умолчанию, когда исходная последовательность пуста, используйте метод FirstOrDefault.

Кроме того, что MSDN говорит о FirstOrDefault ():

Возвращает первый элемент последовательности, или значение по умолчанию, если элемент не найден .

Попробуйте использовать FirstOrDefault():

int index = -1;  
index = (dgv.Rows.Cast<DataGridViewRow>()  
    .Where(r => r.Cells[0].Value.Equals(10))  
    .Select(r => r.Index)).FirstOrDefault();  

ОБНОВЛЕНИЕ:

С «Исправление ошибки LINQ: последовательность не содержит элементов» :

Когда вы получаете ошибку LINQ «Последовательность не содержит элементов», обычно это происходит потому, что вы используете команду First () или Single (), а не FirstOrDefault () и SingleOrDefault ().

Вы можете воспроизвести вашу ошибку:

int[] numbers = { };

int first = numbers.First(number => number > 800); // OUTPUT: Sequence contains 
                                                   // no matching element
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...