微软正式发布C# 10( 四 )


04 结构和匿名类型的表达式
C# 10 支持所有结构的 with 表达式 , 包括记录结构 , 以及匿名类型:
var person2 = person with { LastName = "Kristensen" };
这将返回一个具有新值的新实例 。 你可以更新任意数量的值 。 你未设置的值将保留与初始实例相同的值 。
在本文中了解有关 with 的更多信息
了解有关 with 的更多信息
https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/record#built-in-formatting-for-display
内插字符串改进
当微软在 C# 中添加内插字符串时 , 微软总觉得在性能和表现力方面 , 使用该语法可以做更多事情 。
01 内插字符串处理程序
今天 , 编译器将内插字符串转换为对 string.Format 的调用 。 这会导致很多分配 —— 参数的装箱、参数数组的分配 , 当然还有结果字符串本身 。 此外 , 它在实际插值的含义上没有任何回旋余地 。
在 C# 10 中 , 微软添加了一个库模式 , 允许 API“接管”对内插字符串参数表达式的处理 。 例如 , 考虑 StringBuilder.Append:
var sb = new StringBuilder; sb.Append($"Hello {args[0]}, how are you?");
到目前为止 , 这将使用新分配和计算的字符串调用 Append (string? value) 重载 , 将其附加到 StringBuilder 的一个块中 。 但是 , Append 现在有一个新的重载 Append (refStringBuilder.AppendInterpolatedStringHandler handler) , 当使用内插字符串作为参数时 , 它优先于字符串重载 。
通常 , 当你看到 SomethingInterpolatedStringHandler 形式的参数类型时 , API 作者在幕后做了一些工作 , 以更恰当地处理插值字符串以满足其目的 。 在微软的 Append 示例中 , 字符串“Hello”、args [0] 和“ , how are you?”将单独附加到 StringBuilder 中 , 这样效率更高且结果相同 。
有时你只想在特定条件下完成构建字符串的工作 。 一个例子是 Debug.Assert:
Debug.Assert(condition, $"{SomethingExpensiveHensHere}");
在大多数情况下 , 条件为真 , 第二个参数未使用 。 但是 , 每次调用都会计算所有参数 , 从而不必要地减慢执行速度 。 Debug.Assert 现在有一个带有自定义插值字符串构建器的重载 , 它确保第二个参数甚至不被评估 , 除非条件为假 。
最后 , 这是一个在给定调用中实际更改字符串插值行为的示例:String.Create 允许你指定 IFormatProvider 用于格式化插值字符串参数本身的洞中的表达式:
String.Create(CultureInfo.InvariantCulture, $"The result is {result}");
你可以在本文和有关创建自定义处理程序的本教程中了解有关内插字符串处理程序的更多信息 。
创建自定义处理程序
https://docs.microsoft.com/dotnet/csharp/languagereference/tokens/interpolated#compilation-of-interpolated-strings
内插字符串处理程序的更多信息
https://docs.microsoft.com/dotnet/csharp/whats-new/tutorials/interpolated-string-handler
02 常量内插字符串
如果内插字符串的所有洞都是常量字符串 , 那么生成的字符串现在也是常量 。 这使你可以在更多地方使用字符串插值语法 , 例如属性:
[Obsolete($"Call {nameof(Discard)} instead")]
请注意 , 必须用常量字符串填充洞 。 其他类型 , 如数字或日期值 , 不能使用 , 因为它们对文化敏感 , 并且不能在编译时计算 。
其他改进
C# 10 对整个语言进行了许多较小的改进 。 其中一些只是使 C# 以你期望的方式工作 。
在解构中混合声明和变量
在 C# 10 之前 , 解构要求所有变量都是新的 , 或者所有变量都必须事先声明 。 在 C# 10 中 , 你可以混合:
int x2; int y2; (x2, y2) = (0, 1); // Works in C# 9 (var x, var y) = (0, 1); // Works in C# 9 (x2, var y3) = (0, 1); // Works in C# 10 onwards

特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。