【问题标题】:What is the difference between a regular string and a verbatim string?常规字符串和逐字字符串有什么区别?
【发布时间】:2011-03-19 17:25:47
【问题描述】:

我有 ReSharper 的试用版,它总是建议我将常规字符串切换为逐字字符串。有什么区别?

【问题讨论】:

  • 我从未见过 ReSharper 提出的这个建议。你能举个例子吗?
  • 我刚刚得到它。第一个建议是将其移动到资源中,但第二个建议是使其成为逐字字符串: MessageBox.Show("A platypus must be petted before work can continue.");
  • 我仍然一直都明白。它通常是您想要关闭的更清晰警告之一,因为它建议无缘无故地逐字制作字符串。
  • 如果您喜欢我为 Visual Studio IDE 推荐的功能,请在此处投票:developercommunity.visualstudio.com/idea/602807/…

标签: c# resharper


【解决方案1】:

逐字字符串是不需要转义的字符串,例如文件名:

string myFileName = "C:\\myfolder\\myfile.txt";

string myFileName = @"C:\myfolder\myfile.txt";

@ 符号表示按字面意思读取该字符串,否则不解释控制字符。

【讨论】:

  • 我想知道为什么 Resharper 建议进行此更改。是否有任何 CLR 专家知道是否可以更有效地处理逐字字符串,因为可以忽略转义字符?
  • 我认为 ReSharper 可能建议这样做,因为逐字字符串更具可读性。
  • 我相信这是一种编码约定(我以前从未见过或听说过)。对于字符串,ReSharper 建议将其移动到资源文件中以进行本地化或逐字逐句 - 对于逐字字符串,ReSharper 将不再提供本地化字符串的选项。因此,使所有不需要逐字本地化的字符串似乎是一种约定。
  • 由于不需要解释转义字符,使用逐字字符串会提供更好的性能吗?还是在编译时已经处理了?
  • 通常这种类型的东西是在编译时处理的,如果编译器能够确定该值已设置然后永远不会改变。至少,原始类型就是这种情况。我不太确定复杂的。
【解决方案2】:

这在section 2.4.4.5 of the C# specification:

2.4.4.5 字符串字面量

C# 支持两种形式的字符串文字:常规字符串文字和逐字字符串文字。

常规字符串字面量由用双引号括起来的零个或多个字符组成,如“hello”,并且可能包括简单的转义序列(如制表符的 \t)以及十六进制和 Unicode 转义序列。

逐字字符串文字由一个 @ 字符后跟一个双引号字符、零个或多个字符以及一个结束双引号字符组成。一个简单的例子是@"hello"。在逐字字符串文字中,分隔符之间的字符被逐字解释,唯一的例外是引号转义序列。特别是,简单的转义序列以及十六进制和 Unicode 转义序列不会在逐字字符串文字中进行处理。逐字字符串文字可能跨越多行。

换句话说,@“逐字字符串文字”中唯一的特殊字符是双引号字符。如果你想写一个包含双引号的逐字字符串,你必须写两个双引号。所有其他字符均按字面意思解释。

您甚至可以在逐字字符串文字中添加文字换行符。在常规字符串文字中,您不能有文字换行。相反,您必须使用例如"\n"

逐字字符串文字对于在源代码中嵌入文件名和正则表达式通常很有用,因为这些类型的字符串中的反斜杠很常见,如果使用常规字符串文字,则需要对其进行转义。

从常规字符串文字创建的字符串和从逐字字符串文字创建的字符串在运行时没有区别 - 它们都是 System.String 类型。

【讨论】:

    【解决方案3】:

    字符串和逐字字符串在运行时没有区别。它们仅在编译时有所不同。编译器在逐字字符串中接受的转义序列较少,因此除了引号转义之外,所见即所得。

    您还可以使用逐字字符@,告诉编译器将关键字视为名称:

    var @if = "if";
    //okay, treated as a name
    Console.WriteLine(@if);
    //compiler err, if without @ is a keyword
    Console.WriteLine(if);
    
    var @a = "a";
    //okay
    Console.WriteLine(@a);
    //also okay, @ isn't part of the name
    Console.WriteLine(a);
    

    【讨论】:

      【解决方案4】:

      您也可以使用逐字字符串来创建多行字符串:

      Console.WriteLine(@"This
          is
          a
          Test
          for stackoverflow");
      

      如果没有@,则会出现错误。

      在 VB14 中有一个新功能称为Multiline Strings,它就像 C# 中的逐字字符串。

      专业提示:VB 字符串文字现在与 C# 逐字字符串完全一样。

      【讨论】:

        【解决方案5】:

        常规字符串使用特殊的转义序列来转换为特殊字符。

        /*
        This string contains a newline
        and a tab    and an escaped backslash\
        */
        Console.WriteLine("This string contains a newline\nand a tab\tand an escaped backslash\\");
        

        逐字字符串按原样解释,不翻译任何转义序列:

        /* 
        This string displays as is. No newlines\n, tabs\t or backslash-escapes\\.
        */
        Console.WriteLine(@"This string displays as is. No newlines\n, tabs\t or backslash-escapes\\.");
        

        【讨论】:

          【解决方案6】:

          如果你想抑制 ReSharper 警告,你可以使用:

          Localizable(false)
          

          对于参数、文件位置等,这可能是一个很好的解决方案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-02-26
            • 1970-01-01
            • 2010-09-17
            • 2011-09-05
            相关资源
            最近更新 更多