【.NET Core】深入理解C#中的特殊字符

简介: 【.NET Core】深入理解C#中的特殊字符

一、概述

特殊字符是预定义的上下文字符,用于修饰最前面插入了此类字符的程序元素(文本字符串,标识符或属性名称)。C#支持以下特殊字符:

  • @:逐字字符串标识符字符
  • $: 内插入字符串字符


二、$-- 字符串内插

$ 字符将字符串字面量标识为内插字符串。 内插字符串是可能包含内插表达式的字符串文本 。 将内插字符串解析为结果字符串时,带有内插表达式的项会替换为表达式结果的字符串表示形式。

字符串内插为格式化字符串提供了一种可读性和便捷性更高的方式。它比字符串复合格式设置更容易。

public static void Main(string[] arg)
{
    var name = "Mark";
    var date = DateTime.Now;
    Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
    Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
}

从C#10开始,可以使用内插字符串来初始化常量字符串。仅当内插字符串中的所有内插表达式也是常量字符串时,才可以执行此操作。

2.1 内插字符串的结构

若要将字符串标识为内插字符串,可在该字符串前面加上$符号。字符串字面量开头的$"之间不能有任何空格。

具备内插表达式的项的结构如下所示:

{<interpolationExpression>[,<alignment>][:<formatString>]}
  • interpolationExpression 生成需要设置格式的结果的表达式。null的字符串表示形式为String.Empty。
  • alignment 常数表达式,它的值定义表达式结果的字符串表示形式中的最小字符数。 如果值为正,则字符串表示形式为右对齐;如果值为负,则为左对齐。
  • formatString 受表达式结果类型支持的格式字符串。
public static void Main(string[] arg)
{
   Console.WriteLine($"|{"Left",-7}|{"Right",7}|");
   const int FieldWidthRightAligned = 20;
   Console.WriteLine($"{Math.PI,FieldWidthRightAligned} - default formatting of the pi number");
   Console.WriteLine($"{Math.PI,FieldWidthRightAligned:F2} - display only three decimal digits");
}

从 C# 11 开始,可以在内插表达式中使用换行符,以使表达式的代码更具可读性。

下面的示例展示了换行符如何提高涉及模式匹配的表达式的可读性:

public static void Main(string[] arg)
{
   var safetyScore = 80;
   string message = $"The usage policy for {safetyScore} is" +
          $" {safetyScore switch
                 {
                     > 90 => "Unlimited usage",
                     > 80 => "General usage, with daily safety check",
                     > 70 => "Issues must be addressed within 1 week",
                     > 50 => "Issues must be addressed within 1 day",
                     _ => "Issues must be addressed before continued use",
                 }}";
   Console.WriteLine(message);
}

2.2 内插原始字符串字面量

从C# 11开始,可以使用内插原始字符串字面量。如以下示例所示:

int X=2;
int Y=3;
var pointMessage = $"""The point"{X},{Y}" is {Math.Sqrt(X*X+Y*Y):F3} from the origin""";
Console.WriteLine(pointMessage);

要在结果字符串嵌入{}字符,请让内插原始字符串字面量以多个$字符开头。执行此操作时,任何长度短$字符数的{}字符序列都会嵌入到结果字符串中。若要将任何内插表达式包含该字符串中,需要使用与$字符数相同的大括号数。


如以下示例所示:

int X = 2;
int Y = 3;

var pointMessage = $$"""{The point {{{X}}, {{Y}}} is {{Math.Sqrt(X * X + Y * Y):F3}} from the origin}""";
Console.WriteLine(pointMessage);

内插原始字符串字面量以两个$字符开头。需要将每个内插表达式放在双大括号{{}}之间。单个大括号嵌入到结果字符串中,如果需要重复的{}字符嵌入结果字符串中,请使用相应增加的$字符数来指定内插原始字符串字面量。


2.3 特殊字符

要在内插字符串生成的文本中包含大括"{“或”}",请使用两个大括号,即“{{”或“}}”。有关详细信息。

因为冒号(“:”)在内插表达式中具有特殊含义,为了在内插表达式使用条件运算符,请将表达式放在括号内。

下面示例演示了如何在结果字符串中包含大括号。下面示例演示如何使用条件运算符:

string name = "Horace";
int age = 34;
Console.WriteLine($"He asked, \"Is your name {name}?\", but didn't wait for a reply :-{{");
Console.WriteLine($"{name} is {age} year{(age == 1 ? "" : "s")} old.");

内插逐字字符串以$@字符开头。可以按任意顺序使用$@: $@"..."@$"..."均为有效的内插逐字字符串。


2.4 内插字符串编译

从C#10和.NET 6开始,编译器会检查内插字符串是否被分配给满足内插字符串处理程序模式要求的类型。内插字符串处理程序是一种内插字符串转换为结果字符串的类型。当内插字符串的类型为string时,它由System.Runtime.CompilerServices.DefaultInterpolatedStringHandle处理。


在C# 10之前,如果内插字符串类型为String,则通常将其转换为String.Format方法调用。如果分析的行为等同于串联,则编译器可将String.Format替换为String.Concat。


如果内插字符串类型为IFormattable或FormattableString,则编译器会生成对FormattableStringFactory.Create方法的调用。

三、@-- 逐字字符串标识符

@特殊字符用作原义标识符。通过以下方式使用它:

  • 指示将原义解释字符串。@字符在此实例中定义原义标识符。简单转义序列、十六进制转义序列和Unicode转义序列都将字面解释。只有引号转义序列(“”)不会被字面解释;因为它生成一个双引号。此外。如果是逐字内插字符串,大括号转义序列({{}})不按字面解释;它们会生成单个大括号字符。
string filename1 = @"c:\documents\files\u0066.txt";
string filename2 = "c:\\documents\\files\\u0066.txt";
Console.WriteLine(filename1);
Console.WriteLine(filename2);

使用C#关键字作为标识符。@字符可作为代码元素的前缀,编译器将把此代码元素解释为标识符而非C#关键字。

string[] @for={"John","James","Joan","Jamie"};
for(int ctr = 0; ctr<@for.Length;ctr++)
{
    Console.WriteLine($"Here is your gift, {@for[ctr]}!");
}
  • 使编译器在命名冲突的情况下区分两种属性。属性是派生自Attribute的类。其类型名称通常包含后缀Attribute,但编译器不会强制进行转换。

四、“”“–原始字符串文本

原始字符串字面量以至少三个双引号()字符开始和结束:

var singleLine = """This is a "raw string literal". It can contain characters like \, ' and ".""";

原始字符串字面量可以包含多行:

var xml = """
        <element attr="content">
            <body>
            </body>
        </element>
        """;

以下规则控制多行原始字符串字面量的解释:

  • 左引号和右引号字符必须位于各自的行中
  • 右引号左侧的任何空格将从原始字符串字面量的所有行中删除。
  • 将忽略同一行中左引号后面的空格。
  • 字符串字面量中仅包含左引号后面的空格行

可能需要创建包含三个或更多连续双引号字符的原始字符串字面量。 原始字符串字面量可以至少三个双引号字符的序列开始和结束。 如果字符串字面量包含三个连续双引号,则以四个双引号字符开始和结束原始字符串字面量:

var moreQuotes = """" As you can see,"""Raw string literals""" can start and end with more than three double-quotes when needed."""";

原始字符串字面量还可以与内插字符串结合使用,以在输出字符串中嵌入{}字符。在内插的原始字符串字面量中使用多个$字符,以在输出字符串中嵌入{}字符,而无需对这些字符进行转义。

目录
相关文章
|
4天前
|
Java 物联网 C#
C#/.NET/.NET Core学习路线集合,学习不迷路!
C#/.NET/.NET Core学习路线集合,学习不迷路!
|
8天前
|
Java 物联网 编译器
C#一分钟浅谈:.NET Core 与 .NET 5 区别
本文对比了 .NET Core 和 .NET 5,从历史背景、主要区别、常见问题及易错点等方面进行了详细分析。.NET Core 侧重跨平台支持和高性能,而 .NET 5 在此基础上统一了 .NET 生态系统,增加了更多新特性和优化。开发者可根据具体需求选择合适的版本。
29 7
|
4天前
|
人工智能 开发框架 前端开发
C#/.NET/.NET Core技术前沿周刊 | 第 12 期(2024年11.01-11.10)
C#/.NET/.NET Core技术前沿周刊 | 第 12 期(2024年11.01-11.10)
|
4天前
|
开发框架 网络协议 .NET
C#/.NET/.NET Core优秀项目和框架2024年10月简报
C#/.NET/.NET Core优秀项目和框架2024年10月简报
|
3天前
|
人工智能 开发框架 安全
C#/.NET/.NET Core技术前沿周刊 | 第 13 期(2024年11.11-11.17)
C#/.NET/.NET Core技术前沿周刊 | 第 13 期(2024年11.11-11.17)
|
4天前
|
网络协议 Unix Linux
精选2款C#/.NET开源且功能强大的网络通信框架
精选2款C#/.NET开源且功能强大的网络通信框架
|
4天前
|
程序员 C# 图形学
全面的C#/.NET自学入门指南
全面的C#/.NET自学入门指南
|
28天前
|
JSON C# 开发者
C#语言新特性深度剖析:提升你的.NET开发效率
【10月更文挑战第15天】C#语言凭借其强大的功能和易用性深受开发者喜爱。随着.NET平台的演进,C#不断引入新特性,如C# 7.0的模式匹配和C# 8.0的异步流,显著提升了开发效率和代码可维护性。本文将深入探讨这些新特性,助力开发者在.NET开发中更高效地利用它们。
33 1
|
1月前
|
人工智能 开发框架 Cloud Native
C#/.NET/.NET Core技术前沿周刊 | 第 9 期(2024年10.07-10.13)
C#/.NET/.NET Core技术前沿周刊 | 第 9 期(2024年10.07-10.13)
|
1月前
|
开发框架 前端开发 API
C#/.NET/.NET Core优秀项目和框架2024年9月简报
C#/.NET/.NET Core优秀项目和框架2024年9月简报