通常使用内插字符串作为断言消息,例如:
Debug.Assert(result != x, $"Unexpected result {result}");
但是,在以前的版本中,这将导致在每次调用时都为消息创建一个字符串,包括格式设置结果,即使条件为 true
也是如此。 断言的典型用法是用于应始终为 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)