Поделиться через


Условное вычисление значения строки в методах отладки

В качестве сообщений утверждения обычно используются интерполяции строк, например:

Debug.Assert(result != x, $"Unexpected result {result}");

Однако в предыдущих версиях это приводит к созданию строки для сообщения, включая результат форматирования, при каждом вызове, даже если условие имеет значение true. И типичное использование утверждений заключается в том, что они являются условием, которое всегда должно быть истинным.

В C# 10 добавлена поддержка более эффективной интерполяции строк, включая возможность назначения настраиваемых обработчиков в дополнение к строкам. В .NET 6 класс Debug имеет новые перегрузки Assert, WriteIf и WriteLineIf, которые используют эту функцию для условного вычисления элементов форматирования строк с интерполяцией, только если сообщение является обязательным. Компилятор C# будет предпочитать эти новые перегрузки. Если элементы форматирования были изменены, а программа полагается на то, что эти изменения должны быть видимыми даже в том случае, если утверждение не было инициировано, можно заметить различие в поведении.

Прежнее поведение

В следующем коде всегда будет вызываться r.ToString().

Debug.Assert(true, $"{r.ToString()}");

Новое поведение

В следующем коде r.ToString() никогда не будет вызываться, поскольку сообщение требуется только в том случае, если условие имеет значение false.

Debug.Assert(true, $"{r.ToString()}");

Представленные версии

6.0 RC 1

Тип критического изменения

Это изменение может повлиять на совместимость исходного кода.

Причина изменения

Это изменение было введено для повышения производительности.

Интерполированные строки, используемые с методами Debug, не должны изменять общее состояние. (Эти методы также условны в отношении константы компиляции DEBUG.) Если по какой-либо причине крайне важно сохранить старое поведение, добавьте приведение (string) перед интерполированной строкой. Это приведение приводит к тому, что компилятор привязывается к существующей перегрузке и гарантирует, что строка всегда материализована.

Затронутые API