C#中字符串前面的@是什么?

问题描述 投票:0回答:10

这是 C#(或可能是 VB.net)的 .NET 问题,但我试图找出以下声明之间的区别:

string hello = "hello";

对比

string hello_alias = @"hello";

在控制台打印出来没有区别,长度属性是一样的。

c# .net string verbatim-string
10个回答
978
投票

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

所以

"C:\\Users\\Rich"
@"C:\Users\Rich"

相同

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

@""""
的计算结果为
"


305
投票

这是一个逐字字符串文字。这意味着不应用转义。例如:

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

这里

verbatim
regular
有相同的内容。

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

string select = @"
SELECT Foo
FROM Bar
WHERE Name='Baz'";

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

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

76
投票

“@”还有另一个含义:将其放在变量声明前面可以让您使用保留关键字作为变量名称。

例如:

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

我只发现了一两个合法用途。主要是在 ASP.NET MVC 中,当你想做这样的事情时:

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

这会产生一个 HTML 链接,如:

<a href="/Controller/Action" class="some_css_class">Text</a>

否则,您将不得不使用“Class”,它不是保留关键字,但大写的“C”不遵循 HTML 标准,而且看起来也不正确。


19
投票

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

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

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

string x = "Foo\nbar";

在 VB 中可以这样写:

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

&
是VB字符串连接运算符。
+
同样可以使用。)


12
投票

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

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

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

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


11
投票

这是一个逐字字符串,并更改转义规则 - 现在转义的唯一字符是“,转义为””。这对于文件路径和正则表达式特别有用:

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

等等


9
投票

复制自MSDN

在编译时,逐字字符串将转换为具有所有相同转义序列的普通字符串。因此,如果您在调试器监视窗口中查看逐字字符串,您将看到编译器添加的转义字符,而不是源代码中的逐字版本。例如,逐字字符串

@"C:\files.txt"
将在监视窗口中显示为
"C:\\files.txt"


9
投票

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

所以你可以写:

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

而不是:

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

3
投票

解释很简单。为了表示字符串

"string\"
,编译器需要
"string\\"
,因为
\
是转义字符。如果您使用
@"string\"
代替,您可以忘记
\\


0
投票

对于那些因变量已修改而苦苦挣扎的人。

在我的例子中,Uri 的文件路径:

var sideOne = UserDataPaths.GetDefault().Desktop + "\\TestFolder\\SideOne.png"

var source = new Uri($@"{sideOne}", UriKind.RelativeOrAbsolute);
© www.soinside.com 2019 - 2024. All rights reserved.