Каково приоритетное значение оператора C # нуль-слияния (??)? - PullRequest
19 голосов
/ 04 февраля 2009

Я только что попробовал следующее, идея состояла в том, чтобы объединить две строки, подставив пустую строку для нулей.

string a="Hello";
string b=" World";

- Отладка (забавно, что это печать, не совсем помогает читабельность ...)

 ? a ?? "" + b ?? "" 

-> «Привет»

Правильно:

? (a??"")+(b??"")
"Hello World"

Я как бы ожидал "Hello World" или просто "World", если a равно нулю. Очевидно, что это связано с приоритетом оператора и может быть преодолено в скобках, есть ли где-нибудь, что документирует порядок приоритета для этого нового оператора.

(Понимая, что мне, вероятно, следует использовать stringbuilder или String.Concat)

Спасибо.

Ответы [ 4 ]

35 голосов
/ 04 февраля 2009

Помимо того, что вы хотели бы , чтобы иметь приоритет, что это в соответствии с ECMA, что это в соответствии со спецификацией MS и что на самом деле делает csc, у меня есть один совет:

Не делай этого .

Я думаю, что намного яснее написать:

string c = (a ?? "") + (b ?? "");

В качестве альтернативы, учитывая, что null в конкатенации строк в конечном итоге просто становится пустой строкой, просто напишите:

string c = a + b;

РЕДАКТИРОВАТЬ: Относительно документированного приоритета, как в C # 3.0 spec (документ Word), так и в ECMA-334 , сложение связывает сильнее, чем ??, что связывает сильнее, чем назначение. Ссылка MSDN, приведенная в другом ответе, неверна и причудлива, IMO. На странице, сделанной в июле 2008 года, показано изменение, которое переместило условный оператор - но, по-видимому, неправильно!

6 голосов
/ 04 февраля 2009

Никогда не полагайтесь на приоритет оператора. Всегда явно указывает, как вы хотите, чтобы ваш код действовал. Сделайте себе и другим одолжение, когда вернетесь к своему коду.

(a ?? "") + (b ?? "")

Это не оставляет места для двусмысленности. Двусмысленность - это рассадник жуков.

5 голосов
/ 04 февраля 2009

Приоритет оператора задокументирован на MSDN .

Однако приоритет MSDN противоречит приоритету как в загружаемой спецификации C # также от Microsoft, так и в спецификации для ECMA . Что немного странно.

Независимо от того, как сказал Джон Скит в своем ответе, лучше всего не полагаться на приоритет операторов, а явным образом использовать скобки.

2 голосов
/ 04 февраля 2009

Интересно, что http://msdn.microsoft.com/en-us/library/6a71f45d.aspx и http://en.csharp -online.net / ECMA-334: _14.2.1_Operator_precedence_and_associativity дают различный приоритет ??.

MSDN:

  1. Условный
  2. Назначение
  3. Нулевое слияние
  4. Лямбда

ECMA:

  1. Null Coalescing
  2. Условный
  3. Назначение

Я думаю, что MSDN должен быть неправильным, рассмотрим:

string a = null;
string b = a ?? "foo";
// What is b now?
...