Что означают два знака вопроса вместе в C #? - PullRequest
1457 голосов
/ 15 января 2009

Пробежал по этой строке кода:

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

Что означают два вопросительных знака, это какой-то троичный оператор? Трудно найти в Google.

Ответы [ 17 ]

1954 голосов
/ 15 января 2009

Это оператор слияния null, очень похожий на троичный (немедленный-если) оператор. Смотри также ?? Оператор - MSDN .

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

расширяется до:

FormsAuth = formsAuth != null ? formsAuth : new FormsAuthenticationWrapper();

, который расширяется до:

if(formsAuth != null)
    FormsAuth = formsAuth;
else
    FormsAuth = new FormsAuthenticationWrapper();

В английском это означает «Если то, что слева, не равно нулю, используйте это, в противном случае используйте то, что справа».

Обратите внимание, что вы можете использовать любое их количество по порядку. Следующий оператор назначит первый ненулевой Answer# для Answer (если все ответы нулевые, тогда Answer нулевой):

string Answer = Answer1 ?? Answer2 ?? Answer3 ?? Answer4;

Также стоит упомянуть, хотя приведенное выше расширение концептуально эквивалентно, результат каждого выражения оценивается только один раз. Это важно, если, например, выражение является вызовом метода с побочными эффектами. (Благодарим @Joey за указание на это.)

263 голосов
/ 15 января 2009

Просто потому, что никто еще не произнес волшебные слова: это оператор объединения нулей . Это определено в разделе 7.12 спецификации языка C # 3.0 .

Это очень удобно, особенно из-за того, как оно работает, когда оно используется в выражении несколько раз. Выражение формы:

a ?? b ?? c ?? d

выдаст результат выражения a, если оно не равно нулю, в противном случае попробуйте b, в противном случае попробуйте c, в противном случае попробуйте d. Это короткое замыкание в каждой точке.

Кроме того, если тип d не имеет значения NULL, тип целого выражения также не может иметь значение NULL.

67 голосов
/ 15 января 2009

Это оператор слияния.

http://msdn.microsoft.com/en-us/library/ms173224.aspx

Да, поиск почти невозможен, если вы не знаете, как он называется! : -)

РЕДАКТИРОВАТЬ: И это отличная особенность из другого вопроса. Вы можете связать их.

Скрытые возможности C #?

25 голосов
/ 15 января 2009

Спасибо всем, вот самое краткое объяснение, которое я нашел на сайте MSDN:

// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
20 голосов
/ 15 января 2009

?? для предоставления значения для обнуляемого типа, когда значение равно нулю. Итак, если formsAuth равен нулю, он вернет новый FormsAuthenticationWrapper ().

18 голосов
/ 16 декабря 2013

enter image description here

Два знака вопроса (??) указывают на то, что это оператор объединения.

Оператор объединения возвращает первое значение NULL из цепочки. Вы можете увидеть это видео на YouTube , которое демонстрирует практически все.

Но позвольте мне добавить больше к тому, что говорит видео.

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

Таким образом, если str1 равно null, оно будет пытаться str2, если str2 равно null, оно будет пытаться str3 и т. Д., Пока не найдет строку с ненулевым значением.

string final = str1 ?? str2 ?? str3 ?? str4;

Проще говоря, оператор Coalescing возвращает первое значение NULL из цепочки.

12 голосов
/ 30 июня 2009

Если вы знакомы с Ruby, его ||= мне кажется похожим на C # ??. Вот немного Руби:

irb(main):001:0> str1 = nil
=> nil
irb(main):002:0> str1 ||= "new value"
=> "new value"
irb(main):003:0> str2 = "old value"
=> "old value"
irb(main):004:0> str2 ||= "another new value"
=> "old value"
irb(main):005:0> str1
=> "new value"
irb(main):006:0> str2
=> "old value"

А в C #:

string str1 = null;
str1 = str1 ?? "new value";
string str2 = "old value";
str2 = str2 ?? "another new value";
11 голосов
/ 15 января 2009

Это короткая рука для троичного оператора.

FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();

Или для тех, кто не делает тройной:

if (formsAuth != null)
{
  FormsAuth = formsAuth;
}
else
{
  FormsAuth = new FormsAuthenticationWrapper();
}
11 голосов
/ 22 марта 2013

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

CODE

int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;
10 голосов
/ 30 октября 2016

Как правильно указано в многочисленных ответах, это «оператор слияния нулей» ( ?? ), говоря о котором вы также можете проверить своего двоюродного брата «Нулевой оператор» (?. или ? [), то есть оператор, который много раз используется вместе с ??

Нулевой оператор

Используется для проверки на нулевое значение перед выполнением операции доступа к члену (?. ) или индекса (? [). Эти операторы помогают вам писать меньше кода для обработки нулевых проверок, особенно для спуска в структуры данных.

Например:

// if 'customers' or 'Order' property or 'Price' property  is null,
// dollarAmount will be 0 
// otherwise dollarAmount will be equal to 'customers.Order.Price'

int dollarAmount = customers?.Order?.Price ?? 0; 

по-старому, без ?. и ?? , это

int dollarAmount = customers != null 
                   && customers.Order!=null
                   && customers.Order.Price!=null 
                    ? customers.Order.Price : 0; 

, что более многословно и громоздко.

...