常规字符串和逐字字符串有什么区别?


166

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


3
我从没看过ReSharper的建议。您能举个例子说明这一点吗?
约翰·桑德斯

3
我知道了 第一个建议是将其移到资源上,而第二个建议是将其制成逐字字符串:MessageBox.Show(“鸭嘴兽必须在工作之前被抚摸。”);
B. Clay Shannon 2014年

我一直都知道。通常,它是您要关闭的转发器警告之一,因为它建议使字符串无缘无故地逐字记录。
Dean Swiatek,

如果你喜欢我的建议在Visual Studio IDE功能,请给予好评的位置:developercommunity.visualstudio.com/idea/602807/...
奥利维尔Jacot-Descombes

Answers:


191

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

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

将是

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

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


12
我想知道为什么Resharper建议这样做。是否有任何CLR专家知道是否可以更有效地处理逐字字符串,因为可以忽略转义字符?
马特·彼得森

9
我认为ReSharper建议这样做,因为逐字字符串更具可读性。
andyp

36
我相信这是一种编码约定(我以前从未见过或听过)。对于字符串,ReSharper建议将其移动到资源文件中进行本地化,或使其逐字显示-对于逐字字符串,ReSharper不再提供对字符串进行本地化的选项。因此,使所有不需要本地化的字符串看起来像是惯例。
丹尼尔·布鲁克纳(DanielBrückner)2010年

假设我们为字符串变量分配了字符串文字,字符串myFileName =“ C:\\ myfolder \\ myfile.txt”; 现在,我想将myFileName字符串变量转换为逐字字符串。我该怎么做?这样行吗?字符串verbatimStr = @myFileName;
sanjeev bhusal

3
@sanjeevbhusal:您实际上从未这样做过。@“ C:\ myfolder \ myfile.txt”和“ C:\\ myfolder \\ myfile.txt”对CLR来说是同一件事。基本上,这只是语法糖。
alc6379

68

C#规范的第2.4.4.5节对此进行了介绍:

2.4.4.5字符串文字

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

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

逐字字符串文字包含一个@字符,后跟一个双引号字符,零个或多个字符以及一个结束的双引号字符。一个简单的例子是@“ hello”。在逐字字符串文字中,定界符之间的字符逐字解释,唯一的例外是引号-转义序列。特别是,简单的转义序列以及十六进制和Unicode转义序列不在逐字字符串文字中处理。逐字字符串文字可能跨越多行。

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

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

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

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


27

字符串和逐字字符串之间没有运行时差异。它们只是在编译时有所不同。编译器在逐字字符串中接受较少的转义序列,因此,除了引号转义之外,您还能看到什么。

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

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);

16

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

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

没有@你的错误。

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

多行字符串

专家提示:现在,VB字符串文字完全类似于C#逐字字符串。


13

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

/*
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\\.");

0

如果要删除“重新共享”警告,可以使用:

Localizable(false)

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.