C# 中的三个双引号(triple double quotes)

19

在C#中,三重双引号"""的目的是什么?它似乎用于多行文本。但为什么不使用带有@"..."的单个双引号呢?

string text = """
  some text
  some text
  some text
  """;

5
因为单引号不允许换行。这是很久以前做出的决定,现在无法更改。这就是为什么引入了 """ 的原因。 - freakish
7
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#raw-string-literals - ProgrammingLlama
1
如果我没记错的话,使用三个双引号也可以让你在多行文本中对齐每一行的开头,而不会引入不必要的前导空格。我记不清它是如何工作的,但我之前看过一个YouTube视频。我自己从未使用过,所以无法提供详细信息,但这是值得考虑的事情。 - jmcilhinney
2
多行文本只是其中的一个方面。这种方式允许使用任何文本,并将其作为原始字符串直接插入,无需应用额外的转义。只需使用一系列引号,长度比您的原始字符串中最长的引号系列更长即可。不需要是3个引号,可以是5个、10个甚至更多。 - Ralf
2个回答

22

我认为一个简单的例子可以比许多文字更好地解释。 假设我们有一个 SQL 查询,我们想要保持良好的格式以便于阅读。

如果我们过于简单粗暴,它将无法编译:

string sql = 
  "select id, 
          name
     from MyTable"; // <- Doesn't compile 

我们可以使用@来编译verbatim字符串。
string sql = 
 @"select id, 
          name
     from MyTable"; 

...

// A little bit different format somewhere else in c# code
string sameSql = @"select id, 
                          name
                     from MyTable"; 

但另一个问题出现了:我们有不同的字符串,这就是为什么RDBMS会将它们视为不同的查询,两个版本都会被解析和优化,放入缓存中等等。因此,我们需要多次完成相同的工作(甚至更糟糕的是:解析查询缓存可能会被不同格式相同查询淹没,以至于没有足够的空间来存储其他查询)。

SQL开始:

select id, 
          name
     from MyTable

sameSql 中,我们得到了相同的查询语句,但格式不同:

select id, 
                          name
                     from MyTable

请注意,前导空格被保留(我们使用了verbatim字符串,对吧?)这是一个问题。
解决方案是使用新的"""构造。
string sql = 
 """
    select id, 
           name
      from MyTable
 """; 

...

// A little bit different format
string sameSql = """
                    select id, 
                           name
                      from MyTable
                 """; 


在这两种情况下,我们将获得相同的文本。
select id, 
       name
  from MyTable

查询将被解析、优化并仅缓存一次,C#代码风格被忽略


1
下降票的原因:答案只解释了一个使用情况(OP没有要求),但没有提到其他使用情况(请参见问题的评论)或任何文档; 后半部分隐含地处理了一个目标。由于再次没有引用任何文档,看起来像是利用副作用,在“瞧!”风格中呈现。此外,我解决类似您的目标的方式是将所有空格(引号外)替换为单个空格,这是一种更可靠的解决方案,可以通过正则表达式或迭代方法完成。 - syck

12

来源:C# 11 预览版更新 - 原始字符串字面量

If you work with strings literal that contain quotes or embedded language strings like JSON, XML, HTML, SQL, Regex and others, raw literal strings may be your favorite feature of C# 11. Previously if you copied a literal string with quotes into a C# literal, the string ended at the first double quote with compiler errors until you escaped each one. Similarly, if you copied text with curly braces into an interpolated string literal, each curly bracket was interpreted as the beginning of a nested code expression unless you escape it, generally by doubling the curly bracket.

Raw string literals have no escaping. For example, a backslash is output as a backslash, and \t is output as the backslash and a t, not as the tab character.

Raw string literals start and end with at least three double quotes ("""..."""). Within these double quotes, single " are considered content and included in the string. Any number of double quotes less than the number that opened the raw string literal are treated as content. So, in the common case of three double quotes opening the raw string literals, two double quotes appearing together would just be content. If you need to output a sequence of three or more double quotes, just open and close the raw string literal with at least one more quote than that sequence.

Raw string literals can be interpolated by preceding them with a $. The number of $ that prefixes the string is the number of curly brackets that are required to indicate a nested code expression. This means that a $ behaves like the existing string interpolation – a single set of curly brackets indicate nested code. If a raw string literal is prefixed with $$, a single curly bracket is treated as content and it takes two curly brackets to indicate nested code. Just like with quotes, you can add more $ to allow more curly brackets to be treated as content. For example:

const int veryCold = -30;
const int comfortable = 20;

string jsonString =
  $$"""
  {
    "TemperatureRanges": {
      "Cold": {
        "High": {{comfortable}},
        "Low": {{veryCold}}
      }
    }
  }
  """;

Raw string literals also have new behavior around automatically determining indentation of the content based on leading whitespace. To learn more about this and to see more examples on this feature, check out the docs article Raw String Literals.

P.S. 感谢RoeProgrammingLlama指出本文。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接