Наткнулся на эту строку кода:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
Что означают два вопросительных знака, это какой-то троичный оператор? Трудно найти в Google.
Наткнулся на эту строку кода:
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
Что означают два вопросительных знака, это какой-то троичный оператор? Трудно найти в Google.
Это оператор слияния 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 за указание на это. )
Только потому, что никто еще не произнес волшебные слова: это нуль-оператор . Это определено в разделе 7. 12 из C # 3. 0 спецификация языка .
Это очень удобно, особенно из-за того, как он работает, когда он используется в выражении несколько раз. Выражение формы:
a ?? b ?? c ?? d
выдаст результат выражения a
, если он не равен нулю, в противном случае попробуйте b
, в противном случае попробуйте c
, в противном случае попробуйте d
. Это короткое замыкание в каждой точке.
Кроме того, если тип d
не обнуляется, тип целого выражения также не обнуляется.
Это нулевой оператор объединения.
http: // msdn. Microsoft. ком / EN-US / библиотека / ms173224. aspx
Да, поиск почти невозможен, если вы не знаете, как он называется! :-)
РЕДАКТИРОВАТЬ: И это отличная особенность из другого вопроса. Вы можете связать их
Спасибо всем, вот самое краткое объяснение, которое я нашел на сайте MSDN:
// y = x, unless x is null, in which case y = -1.
int y = x ?? -1;
??
, чтобы обеспечить значение для обнуляемого типа, когда значение равно нулю. Таким образом, если formsAuth равен нулю, он вернет новый FormsAuthenticationWrapper ().
Два знака вопроса (? ? ) указывают, что это оператор объединения.
Оператор объединения возвращает первое значение NON-NULL из цепочки. Вы можете увидеть это видео на YouTube , которое демонстрирует практически все это.
Но позвольте мне добавить больше к тому, что говорит видео.
Если вы видите английское значение объединения, оно говорит: «объединяйтесь». Например, ниже приведен простой объединяющий код, который объединяет четыре строки.
Таким образом, если str1
равен null
, он попытается str2
, если str2
равен null
, он будет пытаться str3
и так далее, пока не найдет строку с ненулевым значением.
string final = str1 ?? str2 ?? str3 ?? str4;
Проще говоря, оператор Coalescing возвращает первое значение NON-NULL из цепочки.
Это короткая рука для троичного оператора.
FormsAuth = (formsAuth != null) ? formsAuth : new FormsAuthenticationWrapper();
Или для тех, кто не делает троичный:
if (formsAuth != null)
{
FormsAuth = formsAuth;
}
else
{
FormsAuth = new FormsAuthenticationWrapper();
}
Если вы знакомы с 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";
Ничего опасного в этом нет. На самом деле это красиво. Вы можете добавить значение по умолчанию, если это желательно, например:
КОД
int x = x1 ?? x2 ?? x3 ?? x4 ?? 0;
Только для вашего развлечения (зная, что вы все ребята из C # ;-).
Я думаю, что он возник в Smalltalk, где он существует уже много лет. Это определяется там как:
в объекте:
? anArgument
^ self
в UndefinedObject (он же класс nil):
? anArgument
^ anArgument
Есть как оценить (? ) и не оценочные версии (? ? ) этого.
Это часто встречается в методах-получателях для приватно-инициализированных частных (экземпляров) переменных, которые остаются нулевыми до тех пор, пока они действительно не понадобятся
оператор коалесцирования
это эквивалентно
FormsAuth = formsAUth == null ? new FormsAuthenticationWrapper() : formsAuth
Некоторые примеры получения значений с использованием коалесценции здесь неэффективны.
То, что вы действительно хотите, это:
return _formsAuthWrapper = _formsAuthWrapper ?? new FormsAuthenticationWrapper();
или
return _formsAuthWrapper ?? (_formsAuthWrapper = new FormsAuthenticationWrapper());
Это предотвращает воссоздание объекта каждый раз. Вместо того, чтобы приватная переменная оставалась нулевой, а новый объект создавался при каждом запросе, это гарантирует, что приватная переменная будет назначена, если будет создан новый объект.