Побочные эффекты, короткое замыкание и оператор вызова метода распространения null (?.)

Когда целевой объект имеет значение null в условном доступе к члену/операторе распространения null, а член является методом, оцениваются ли аргументы метода?

То есть в следующем коде вызывается g()?

SomeClass x = null;
x?.Foo(g());

Как насчет h() в:

SomeClass x = null;
x?.Bar($"h = {h()}");

SharpLab помещает оценку аргумента в блок if, поэтому она будет пропущена. Но гарантируется ли это спецификацией или деталями реализации?


person Ben Voigt    schedule 27.06.2018    source источник
comment
Вы можете просто запустить код, который вы уже написали, и очень быстро выяснить, действительно ли вызывается метод. Если вы хотите узнать, что говорится в спецификациях по этому вопросу, прочитайте спецификации.   -  person Servy    schedule 27.06.2018
comment
Почему бы не попробовать это на себе?   -  person HimBromBeere    schedule 27.06.2018
comment
But is this guaranteed by the specification or an implementation detail? (В дополнение к ответу HimBromBeere) Посмотрите черновик спецификации С# 6.0: docs.microsoft.com/en-us/dotnet/csharp/language-reference/ То, что вы ищете, находится ближе к концу раздела Null-conditional operator.   -  person    schedule 27.06.2018
comment
@Servy: Я ДЕЙСТВИТЕЛЬНО запустил код, который привел к последнему абзацу.   -  person Ben Voigt    schedule 28.06.2018
comment
@Servy: Кроме того, я не уверен, где найти спецификацию, включающую последние версии C#, ни одна из них не установлена ​​вместе с Visual Studio, как это было со старыми спецификациями ... документации, которую я нашел, не хватало конкретики и не было сказать, что происходит с аргументами.   -  person Ben Voigt    schedule 28.06.2018
comment
@elgonzo: Спасибо, это можно было бы превратить в отличный ответ (объясняя, что именно происходит со списками аргументов, которые появляются в грамматических постановках, но нигде в семантическом объяснении). Похоже, что правило замены текста указывает на ожидаемое поведение. Не очень приятно определять вещи с помощью текстовых замен, но C# делал это раньше (например, преобразовывал LINQ в последовательности вызовов методов и лямбда-выражений).   -  person Ben Voigt    schedule 28.06.2018
comment
@Servy: я рад, что engonzo предоставил ссылку на правильный абзац спецификации, потому что в собственном оглавлении спецификации его нет, и я бы никогда не подумал искать доступ к нулевому члену, который абсолютно является бинарный оператор, внутри раздела об унарных операторах.   -  person Ben Voigt    schedule 28.06.2018


Ответы (1)


Хотя вы могли бы легко проверить, выполняется ли g или нет, вот объяснение почему. null-conditional-operator — это просто ярлык для простой nullcheck:

«[Оператор с нулевым условием] Проверяет значение левого операнда для null перед выполнением операции доступа к члену (?.) или индекса (?[]); возвращает null, если левый операнд оценивается как null».

Таким образом, ваш код эквивалентен следующему:

if(x != null)
{
    x.Foo(g());
}
person HimBromBeere    schedule 27.06.2018
comment
Тест не говорит вам, что гарантирует язык, а только то, как текущая реализация (вы тестируете) с текущим JIT-компилятором (вы тестируете) обрабатывает этот случай. Я бы не рекомендовал тестировать в качестве решения все, что может потребоваться для переноса между версиями ОС или .Net Framework. - person NetMage; 27.06.2018
comment
@NetMage Верно, но на самом деле вопрос состоит из двух частей: что происходит и почему это происходит. Первое можно легко определить с помощью теста, который на самом деле не охвачен моим ответом. С другой стороны, мой ответ в основном касается второго пункта. - person HimBromBeere; 27.06.2018
comment
На самом деле я думаю, что ни один из них не имеет эффективного ответа, поскольку у вас нет возможности определить, действительно ли .Net Core в Linux (или даже C# в .Net 4.7.2 в Windows) эквивалентен вашему примеру кода без ссылки на стандарт. - person NetMage; 27.06.2018
comment
Оценка аргументов не является частью доступа к членам, поэтому знание того, что доступ к членам не выполняется, ничего не говорит нам о побочных эффектах аргументов. И вы должны попытаться прочитать весь вопрос, где я сказал, какое поведение я наблюдал, вместо того, чтобы рассказывать мне, как легко это попробовать. - person Ben Voigt; 28.06.2018