普通字符串和一字不差的字符串有什么区别?

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

96567 次浏览

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

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

就是

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

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

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

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

这在 C # 规范的第2.4.4.5节中有所涉及:

2.4.4.5字符串字面值

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

一个常规的字符串文字由包含在双引号中的零个或多个字符组成,如“ hello”中,并且可能包含简单的转义序列(例如用 t 表示制表符)和十六进制和 Unicode 转义序列。

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

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

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

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

在运行时,由普通字符串文字创建的字符串和由逐字符串文字创建的字符串没有区别——它们都是 System.String类型。

字符串和逐字字符串在运行时没有区别。它们只是在编译时不同。编译器在逐字字符串中接受较少的转义序列,所以除了引号转义之外,“你看到的就是你得到的”。

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

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

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

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

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

在 VB14中有一个称为 Multiline Strings的新特性,它类似于 C # 中的一字不差的字符串。

Multiline Strings

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

如果要禁止显示 ReSharper 警告,可以使用:

Localizable(false)

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