Смешивание выходных и именованных параметров в C#: почему выходному параметру тоже нужно дать имя?

Короткая версия: именованный аргумент, следующий за аргументом out, вызывает ошибку компилятора, но я не могу найти поддержку такого поведения в спецификацию языка.

Длинная версия:

Я использую перегрузку с тремя параметрами Enum.TryParse, но я бы предпочел назвать параметр ignoreCase, чтобы сделать мой код понятнее, вызов типа:

MyEnum res;
b = Enum.TryParse(inputString, true, out res);

оставляет неясным значение логического значения (если только этот метод не известен 1).Следовательно, я хотел бы использовать:

b = Enum.TryParse(inputString, out res, ignoreCase: true);

Однако компилятор сообщает об этом как об ошибке:

Именованный аргумент 'ignoreCase' указывает параметр, для которого уже задан позиционный аргумент

, и IDE выделяет параметр ignoreCase. VS2010, ориентированный на .NET 4, и бета-версия VS11, ориентированная на 4 или 4.5, дают одинаковый результат. Во всех случаях присваивание имени параметру outустраняет ошибку.

b = Enum.TryParse(inputString, result: out res, ignoreCase: true);

Я пробовал это с помощью ряда различных методов (включая избегание дженериков) 2, как из фреймворка, так и в моей сборке: всегда один и тот же результат: параметр outза которым следует именованный параметр, выдает ошибку.

Я не вижу причин для этой ошибки, и §7.5.1 Списки аргументовспецификации C# Language: Version 4.0, по-видимому, не содержит никаких причин, по которым out, за которым следует именованный параметр, должно привести к ошибке. Текст ошибки, по-видимому, поддерживает интерпретацию ошибки: нет позиционного аргумента, который мог бы соответствовать ignoreCase.

Я неправильно прочитал спецификацию? Или это ошибка компилятора?

Обновление C# 7.2

Это ограничение на то, что все именованные аргументы должны следовать за позиционными аргументами при вызове, было снято в C# 7.2.

См. https://docs.microsoft.com/en-gb/dotnet/csharp/whats-new/csharp-7-2#non-trailing-named-arguments.


1Следовательно, в Руководстве по проектированию фреймворка рекомендуется отдавать предпочтение параметрам enum.

2Например: дано:

private static void TestMethod(int one, float two, out string three) {
  three = "3333";
}

этот этот вызов также дает ту же ошибку для именованного параметра, если параметр outтакже не именован:

TestMethod(1, out aString, two: 1.0f);

5
задан Richard 4 January 2019 в 14:29
поделиться