Проверьте, является ли список пустым перед использованием linq - PullRequest
0 голосов
/ 08 ноября 2019

Используя LINQ, я хочу проверить, если myList! = Null, а затем выполнить Where.

Я знаю, что могу написать

if (myList != null { myList.Where(p => p.x == 2 && p.y == 3); }

Но я хочу использовать: myList?.Where(p => p.x == 2 && p.y == 3);

Это работает?

Если нет, то какие еще элегантные решения вы знаете?

Ответы [ 2 ]

6 голосов
/ 08 ноября 2019

Да, list?.Where(i => i > 1) является допустимым выражением, которое называется «оператор распространения с нулевым значением».

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

var result = list?.Where(i => i > 1)?.Select(i => i * 2)?.Where(i => i % 2 == 0)?.ToList();
// result can be null and still requires check for null

.. Какие еще элегантные решения вы знаете?

Другим элегантным решением было бы убедиться, что всякий раз, когда функция возвращает коллекцию, она никогда не возвращает null, но пустую коллекцию.

Такое соглашение сделает ваш код более легким для чтения и понимания реальных намерений кода, облегчит тестирование (меньше тестовых случаев для тестирования), меньше "шумных проверок на ноль".

Примечаниечто методы расширения LINQ никогда не возвращают null.

Если вы используете библиотеки, которые возвращают null для коллекции, но у вас нет доступа к коду - «конвертируйте» null в пустую коллекцию и продолжайте использовать в качестве допустимой коллекции.

var checkedList = givenList ?? Enumerable.Empty<int>();
checkedList.Where(i => i > 1).ToList();

Если вы часто этим занимаетесь, создайте метод расширения.

public IEnumerable<T> EmptyIfNull(this IEnumerable<T> source)
{
    return source ?? Enumerable.Empty<T>();     
}

Использование

var result = givenList.EmptyIfNull().Where(i => i > 1).ToList();
4 голосов
/ 08 ноября 2019

Если вы строите с использованием C # 6 / Visual Studio 2013 или более поздней версии, вы можете написать:

var result = myList?.Where(p => p.x == 2 && p.y == 3);

Так что, если myList равно null, Where не оценивается и result будет null, иначе типа результирующего запроса (IEnumerable<T> или IQueryable<T>).

Нулевые условные операторы

Также вы можете написать:

var result = myList?.Where(p => p.x == 2 && p.y == 3) ?? someValue;

Таким образом, если myList равно null, result будет назначено someValue.

Нулевой оператор объединения

Вы можете проверить опцию в Project Settings > Build > Advanced options > Language version.

...