IRONSOFTWAREHOME

在 10 分钟或更短时间内实现 C# 10 和 .NET 6 中的常数插值

10 分钟内即可在 C# 10 和.NET 6 中实现常量插值

Tim Corey

6 分 14 秒

随着每个新版本的发布,C# 在功能和优雅性方面不断进步,为开发人员提供更简洁、更高效的代码编写方式。 C# 10 中引入的其中一项新增功能是常量插值字符串——该功能允许开发人员在常量中使用字符串插值。

在此功能出现之前,如果您尝试使用插值创建常量字符串(例如,$"{companyName} Products"),编译器会抛出错误。 你只能将普通的字符串字面量赋值给常量值,这在构建常量消息或属性字符串时常常会导致代码重复或笨拙。

现在,从 C# 10 和 .NET 6 开始,您可以在编译时直接使用字符串插值将常量组合在一起。这项改进不仅使您的代码更简洁,而且还能提高效率,因为所有值都会在程序运行之前进行求值。

为了更清晰地理解其工作原理,Tim Corey 在他的视频" 10 分钟内掌握 C# 10 和 .NET 6 中的常量插值"中,一步步地讲解了这一概念。Tim 以他一贯简洁实用的教学风格,解释了这项新特性的作用、它与传统字符串连接的区别,以及它在哪些情况下特别有用——尤其是在属性中。

那么让我们一起来看看 Tim 的解释,了解 C# 中的常量插值字符串究竟是如何工作的,以及为什么它们对开发人员来说是一个有用的补充。

简介

在这段视频中,Tim 解释了插值字符串(即使用熟悉的美元符号 ($) 语法的字符串)现在可以在常量表达式中使用,这是以前无法实现的。 这一小小的改变使得持续的弦线制作更加容易、干净、易于维护。

探索 .NET 6 中的常量

Tim 打开了一个 .NET 6 控制台应用程序,并删除了样板代码,以便完全专注于常量定义。

他从最基本的常量字符串声明开始:

const string companyName = "Acme";

这是一个简单的字符串字面量,被赋值为一个常量字符串。 像这样的常量是在编译时求值的,这意味着它们的值是固定的,并嵌入到编译后的程序中。

但 Tim 很快就提出了一个核心问题:如果我们想将常量字符串合并在一起,或者使用插值将值直接嵌入到其他字符串中,该怎么办?

在 C# 9 及更早版本中,你无法这样做:

const string productName = $"{companyName} Anvils"; // Not allowed before C# 10

这行代码会引发编译时错误,因为字符串插值不支持常量表达式。

C# 10中的常量插值字符串

正如 Tim 所演示的那样,在 C# 10 中,编译器现在支持常量插值字符串——只要其中的所有插值表达式本身都是常量即可。

所以下面的例子现在可以完美运行了:

const string productName = $"{companyName} Anvils";

这是一个常量插值字符串,这意味着编译器会在编译时而不是运行时计算该插值字符串。程序运行时不会进行额外的字符串连接或字符串格式化——编译器会生成一个类似"Acme Anvils"的单个常量字符串字面量。

Tim 解释说,如果我们把 companyName 的值从"Acme"改为"ABC",编译器会自动为 productName 生成"ABC Anvils"。 这是编译时字符串构造,而不是运行时插值。

这项改进使得合并常量字符串变得更加容易,无需使用 + 连接或手动重复值。

嵌套常量插值

蒂姆更进一步,给出了另一个恒定的定义:

const string productDescription = $"{productName} are the best way to crush unsuspecting roadrunners.";

这是一个嵌套插值的例子,其中一个常量插值字符串(productName)被用在另一个常量插值字符串中。

编译器将所有这些都视为常量表达式,在编译时生成一个单一的、不可变的字符串表示形式。

当 Tim 运行该程序时,输出结果为:

Acme Anvils are the best way to crush unsuspecting roadrunners.

这证实了即使跨越多个常量,常量插值也能无缝运行。

常数为何重要

这时,蒂姆停下来解释了为什么常量(以及现在的常量插值字符串)是有益的。

他指出,常量非常节省内存,因为它们的值直接存储在编译后的代码中,而不是作为单独的实例存储在内存中。

相比之下,以前开发人员需要类似功能时,通常使用只读字段:

readonly string companyName = "Acme";

但 Tim 指出,只读字段与常量字段不同——它们在运行时进行求值,这会消耗更多内存并阻止编译时优化。

借助常量插值字符串,我们现在可以编写富有表现力且可重用的格式化字符串,这些字符串在编译时保持常量,从而提高清晰度和性能。

实际示例——在属性中使用常量

蒂姆随后介绍了一个现实世界的场景,在这个场景中,这项新功能——属性——大放异彩。

他在 Main() 函数内部定义了一个简单的局部方法:

void SayHi() { }

然后他尝试使用引用某个变量的字符串消息来应用 [Obsolete] 属性:

string myCompany = "Tim's Company";
[Obsolete($"This is no longer used for {myCompany}")]

这样做会失败,因为属性只能接受常量表达式作为参数。 由于 myCompany 是一个变量,而不是常量,因此编译器会报错。

Tim 解释说,该属性的消息必须是编译时常量——它不能依赖于运行时值或实例变量。

然而,得益于 C# 10 中的常量插值字符串,我们现在可以安全地做到这一点:

const string productName = $"{companyName} Anvils";
[Obsolete($"This is no longer used for {productName}")]

在这里,编译器识别出 companyName 和 productName 都是常量,因此整个插值字符串是一个常量表达式。

编译器在编译时生成格式化字符串,使其在属性中有效。

这个例子完美地说明了为什么常量插值不仅仅是语法糖——它实现了新的场景,例如直接在属性或元数据中使用格式化的编译时字符串。

幕后揭秘——编译器如何处理

Tim 在视频中没有深入讲解编译器内部的底层原理,但这个概念与 C# 10 中插值字符串处理程序的工作方式密切相关。

一般来说,当编译器遇到插值字符串时,它会创建类似于格式化字符串操作的代码,在后台生成类似 AppendLiteral() 和 AppendFormatted() 的调用。

但是,在处理常量插值字符串时,编译器会在编译时评估所有内容——生成的 IL 代码中不会发出任何插值字符串处理程序或方法调用。

这意味着生成的值与任何字符串字面量的行为完全相同,但您仍然可以使用来自其他常量的嵌入式表达式来组合它。

它巧妙地平衡了表现力和效率——编译器静态地处理字符串构造,确保零运行时成本。

何时使用常量插值字符串

蒂姆承认,并非所有人每天都会使用此功能。 很少定义常量或编写属性的开发人员可能不会立即受益。

但是,对于那些创建大量编译时定义、常量消息或属性元数据的人来说,此功能简化了代码并防止了字符串连接造成的混乱。

它也更安全——因为常量是不可变的,并且由编译器检查,所以可以消除动态连接字符串或管理不当的变量带来的错误。

这能使你的代码更健壮、更易读、更易于维护。

结论

视频结尾,蒂姆邀请开发者们思考一下,他们是否会在项目中使用常量插值字符串。 有些人可能认为它们对于更清晰的编译时格式化字符串至关重要,而另一些人则可能认为它们只是一种小小的便利。

无论如何,Tim 的演示准确地展示了如何有效地实现和应用此功能。

总之:

  • 常量插值字符串允许在常量内使用插值表达式。

  • 它们在编译时进行求值,生成高效的字符串字面量。

它们用更简洁的语法取代了重复的字符串连接。

  • 它们在属性、基于常量的配置和元数据消息中特别有用。

通过将可读性与编译时安全性相结合,C# 10 的常量插值是朝着富有表现力和高效的 C# 编程迈出的又一步——正如 Tim Corey 的例子清楚地表明的那样。

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Let's Stay in Touch!

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy

Key in blue circle

立即获取免费的 30 天试用版密钥

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥
无需信用卡或创建账户