2010-08-13 2 views
6

Насколько я понимаю, метод linq FirstOrDefault() возвращает null, если набор записей пуст. Почему нельзя использовать оператор ?? против функции? Как так:FirstOrDefault() не может соединиться с? оператор

Double d = new Double[]{}.FirstOrDefault() ?? 0.0; 


Update

Я не хочу, чтобы проверить, если d является null позже в моем коде. И делать:

Double d new Double[]{}.FirstOrDefault() == null 
     ? 0.0 
     : new Double[]{}.FirstOrDefault(); 

... или:

var r = new Double[]{}.FirstOrDefault(); 

Double d = r == null ? 0.0 : r; 

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

+0

Во время тестирования вы можете заменить 'new Double [] {}. FirstOrDefault();' на 'default (double)'. – Kobi

ответ

10

На самом деле, FirstOrDefault<T>() возвращает T, который является либо значением или default(T).

default(T) либо null или (T)0 для типов значений (например, double)

11

Поскольку оператор нулевой коалесценции (??) применяется только к ссылочным типам с нулевым значением, тогда как Double является типом значения. Вместо этого вы можете использовать нулевую двойку (double?).

+6

И даже это работало «0.0», в этом случае избыточно. – FuleSnabel

+1

@FuleSnabel, абсолютно, поскольку '0.0' является значением по умолчанию double в любом случае. –

1

Изготовление nullable должно работать. Но, то ваш делать это nullable, все зависит от сценария ...

Double d = new Double?[] { }.FirstOrDefault() ?? 0.0; 
5

Метод называется FirstOrDefault не FirstOrNull, т.е. он возвращает 0, значение по умолчанию двойной все равно так не существует потребность в .

+0

Принял бы ваш ответ. Но Джеймс Карран представил более сложную задачу. Спасибо, Бен. – roosteronacid

0

Хотя другие ответили, почему у вас проблемы с компиляцией, вы правы, что это проблематично для типов значений. Насколько мне известно, в этом случае нет способа узнать, был ли результат нуля равен нулю, потому что первый элемент действительно был нулевым, или потому, что IEnumerable<double> был пуст.

В примере вы дали значение запасной вариант равен нулю в любом случае, так что все, что вам нужно:

var r = new double[]{...}.FirstOrDefault(); 

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

var r = !myDoubles.Any() ? fallback : myDoubles.First(); 

или

var r = myDoubles.Cast<double?>().FirstOrDefault() ?? fallback; 

Если у вас есть Zen Linq Extensions, вы можете сделать:

Смежные вопросы