Условное вычисление значения строки в методах отладки
В качестве сообщений утверждения обычно используются интерполяции строк, например:
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
- System.Diagnostics.Debug.Assert(Boolean, String)
- System.Diagnostics.Debug.Assert(Boolean, String, String)
- System.Diagnostics.Debug.Assert(Boolean, String, String, Object[])
- System.Diagnostics.Debug.WriteIf(Boolean, String)
- System.Diagnostics.Debug.WriteIf(Boolean, String, String)
- System.Diagnostics.Debug.WriteIf(Boolean, Object, String)
- System.Diagnostics.Debug.WriteLineIf(Boolean, String)
- System.Diagnostics.Debug.WriteLineIf(Boolean, String, String)
- System.Diagnostics.Debug.WriteLineIf(Boolean, Object, String)