我有一个Resharper的试用版,它总是建议我将常规字符串切换为逐字字符串。有什么区别?
答案 0 :(得分:171)
逐字字符串是一个不需要转义的字符串,如文件名:
string myFileName = "C:\\myfolder\\myfile.txt";
将是
string myFileName = @"C:\myfolder\myfile.txt";
@符号表示从字面上读取该字符串,否则不解释控制字符。
答案 1 :(得分:64)
这涵盖在section 2.4.4.5 of the C# specification:
中2.4.4.5字符串文字
C#支持两种形式的字符串文字:常规字符串文字和逐字字符串文字。
常规字符串文字由用双引号括起来的零个或多个字符组成,如“hello”中所示,并且可以包括简单转义序列(例如用于制表符的\ t)和十六进制和Unicode转义序列。
逐字字符串文字由@字符后跟双引号字符,零个或多个字符以及结束双引号字符组成。一个简单的例子就是@“你好”。在逐字字符串文字中,分隔符之间的字符是逐字解释的,唯一的例外是quote-escape-sequence。特别是,简单的转义序列和十六进制和Unicode转义序列不会在逐字字符串文字中处理。逐字字符串文字可以跨越多行。
换句话说,@“逐字字符串文字”中唯一的特殊字符是双引号字符。如果您希望编写包含双引号的逐字字符串,则必须编写两个双引号。所有其他字符都按字面解释。
您甚至可以在逐字字符串文字中包含文字新行。在常规字符串文字中,您不能使用文字新行。相反,您必须使用例如"\n"
。
Verbatim字符串文字对于在源代码中嵌入文件名和正则表达式通常很有用,因为这些类型的字符串中的反斜杠很常见,如果使用常规字符串文字则需要进行转义。
在运行时,从常规字符串文字创建的字符串与从逐字字符串文字创建的字符串之间没有区别 - 它们都是System.String
类型。
答案 2 :(得分:24)
字符串和逐字字符串之间没有运行时差异。它们在编译时只是不同的。编译器在逐字字符串中接受较少的转义序列,因此您可以看到除了引用转义之外的其他内容。
您还可以使用逐字符@来告诉编译器将关键字视为名称:
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);
答案 3 :(得分:15)
您也可以使用逐字字符串来创建多行字符串:
Console.WriteLine(@"This
is
a
Test
for stackoverflow");
没有@
您收到错误。
在VB14中有一个名为Multiline Strings
的新功能,它就像C#中的逐字字符串。
专业提示:VB字符串文字现在与C#逐字字符串完全相同。
答案 4 :(得分:12)
常规字符串使用特殊转义序列转换为特殊字符。
/*
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\\.");
答案 5 :(得分:0)
如果要取消显示ReSharper警告,可以使用:
Localizable(false)
对于参数,文件位置等而言,这可能是一个很好的解决方案。