关于.NET:C#中字符串前面的@是什么?

What's the @ in front of a string in C#?

这是C(或者可能是vb.net)的.NET问题,但我正在尝试找出以下声明之间的区别:

1
string hello ="hello";

VS

1
string hello_alias = @"hello";

在控制台上打印没有区别,长度属性相同。


它将字符串标记为逐字字符串文字-忽略字符串中通常被解释为转义序列的任何内容。

因此,"C:\\Users\
ich"
@"C:\Users
ich"
相同。

有一个例外:双引号需要一个转义序列。要转义双引号,需要将两个双引号放在一行中。例如,@""""评估为"


它是一个逐字字符串。这意味着没有应用转义。例如:

1
2
string verbatim = @"foo\bar";
string regular ="foo\\bar";

这里,verbatimregular的内容相同。

它还允许多行内容-这对于SQL来说非常方便:

1
2
3
4
string select = @"
SELECT Foo
FROM Bar
WHERE Name='Baz'"
;

逐字字符串文字所需的转义的一个位是获得双引号("),您可以通过将其加倍来实现:

1
2
string verbatim = @"He said,""Would you like some coffee?"" and left.";
string regular ="He said, "Would you like some coffee?" and left.";


"@"还有另一个含义:将它放在变量声明前面,可以使用保留关键字作为变量名。

例如:

1
2
string @class ="something";
int @object = 1;

我只找到一两个合法的用途。主要在ASP.NET MVC中,当您要执行以下操作时:

1
<%= Html.ActionLink("Text","Action","Controller", null, new { @class ="some_css_class" })%>

它会产生一个HTML链接,比如:

1
Text

否则,您将不得不使用"class",它不是保留关键字,但大写的"c"不遵循HTML标准,只是看起来不正确。


既然您也明确要求使用vb,那么让我补充一下,这个逐字字符串语法不存在于vb中,只存在于c_中。相反,所有字符串在VB中都是逐字的(除了不能包含换行符这一事实,与C逐字字符串不同):

1
2
Dim path ="C:\My\Path"
Dim message ="She said,""Hello, beautiful world."""

转义序列在VB中不存在(除了引号字符的加倍,如在C逐字字符串中),这使得一些事情更加复杂。例如,要在VB中编写以下代码,需要使用连接(或任何其他构造字符串的方法)。

1
2
string x ="Foo
bar"
;

在VB中,这将写如下:

1
Dim x ="Foo" & Environment.NewLine &"bar"

(&是vb字符串连接运算符。可同样使用+


http://msdn.microsoft.com/en-us/library/aa691090.aspx

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

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

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


从msdn复制:

At compile time, verbatim strings are converted to ordinary strings with all the same escape sequences. Therefore, if you view a verbatim string in the debugger watch window, you will see the escape characters that were added by the compiler, not the verbatim version from your source code. For example, the verbatim string @"C:\files.txt" will appear in the watch window as "C:\\files.txt".


这是一个逐字字符串,并更改转义规则-现在转义的唯一字符是",转义到""。这对于文件路径和regex尤其有用:

1
2
3
4
5
var path = @"c:\some\location";
var tsql = @"SELECT *
            FROM FOO
            WHERE Bar = 1"
;
var escaped = @"a"" b";


@放在字符串前面可以使用特殊字符,如反斜杠或双引号,而不必使用特殊代码或转义字符。

所以你可以写:

1
string path = @"C:\My path";

而不是:

1
string path ="C:\\My path\";

解释很简单。为了表示字符串"string\",编译器需要"string\\",因为\是一个转义字符。如果您使用@"string\",您可以忘记\\