关于c#:常规字符串和逐字字符串之间有什么区别?

What is the difference between a regular string and a verbatim string?

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


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

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

将是

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

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


本规范第2.4.4.5节包括:

2.4.4.5 String literals

C# supports two forms of string literals: regular string literals and verbatim string literals.

A regular string literal consists of zero or more characters enclosed in double quotes, as in"hello", and may include both simple escape sequences (such as \t for the tab character) and hexadecimal and Unicode escape sequences.

A verbatim string literal consists of an @ character followed by a double-quote character, zero or more characters, and a closing double-quote character. A simple example is @"hello". In a verbatim string literal, the characters between the delimiters are interpreted verbatim, the only exception being a quote-escape-sequence. In particular, simple escape sequences and hexadecimal and Unicode escape sequences are not processed in verbatim string literals. A verbatim string literal may span multiple lines.

换句话说,@"Verbatim string literal"中唯一的特殊字符是双引号字符。如果要编写包含双引号的逐字字符串,必须编写两个双引号。所有其他字符都是逐字解释的。

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

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

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


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

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

1
2
3
4
5
6
7
8
9
10
11
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);

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

1
2
3
4
5
Console.WriteLine(@"This
    is
    a
    Test
    for stackoverflow"
);

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

在vb14中,有一个新功能叫做Multiline Strings,它就像c_中的逐字字符串。

Multiline Strings

Pro tip: VB string literals are now exactly like C# verbatim strings.


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

1
2
3
4
5
6
/*
This string contains a newline
and a tab    and an escaped backslash\
*/

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

逐字字符串被解释为原样,而不转换任何转义序列:

1
2
3
4
5
6
/*
This string displays as is. No newlines
, tabs\t or backslash-escapes\\.
*/

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