C#の文字列の前にある@は何ですか?


604

これはC#(または場合によってはVB.net)に対する.NETの質問ですが、次の宣言の違いを理解しようとしています。

string hello = "hello";

string hello_alias = @"hello";

コンソールで出力しても違いはありません。長さのプロパティは同じです。


逐語的文字列の書式設定を改善するためのVisual Studio IDEに対する私の提案(および賛成投票)を参照してください:複数行の逐語的文字列をインデントします
Olivier Jacot-Descombes

明確にするために、上記の例はを使用しても使用しなくてもまったく同じ結果を生成してい@ます。
Miro J.

回答:


768

文字列を逐語的な文字列リテラルとしてマークします。通常、エスケープシーケンスとして解釈される文字列内の文字は無視されます。

だから"C:\\Users\\Rich"と同じです@"C:\Users\Rich"

例外が1つあります。二重引用符にはエスケープシーケンスが必要です。二重引用符をエスケープするには、2つの二重引用符を続けて配置する必要があります。たとえば、はに@""""評価され"ます。


1
@RichardEverett私は答えを理解しました、しかし私の疑問はこの機能の実際の使用は何ですか?
アルン2014年

24
@Arunエスケープする必要があることが多い正規表現定義などを含む文字列を処理する場合に非常に便利です
James Thorpe

25
+複数行のコンテンツ
Jaider

4
コールで{{通常のブレースを使用する場合も、ブレースを2重にする必要がありstring.Formatます。
Dave Cousineau 2016年

4
@RichardEverettは、行を分割することなく複数行の文字列リテラルを作成するのに非常に便利です。
John Mott

256

それは逐語的な文字列リテラルです。つまり、エスケープは適用されません。例えば:

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

こちらverbatimregular同じ内容です。

また、複数行のコンテンツも可能です。これはSQLに非常に便利です。

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

逐語的文字列リテラルに必要なエスケープの1ビットは、二重引用符( ")を取得することです。

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

16
また、変数名などとして予約語を使用することもできます。public int GetValueOrDefault(int @default);のように。
11:09にSvish

5
Svish:真実ですが、この特定の質問とは無関係です。
Jon Skeet、

63

「@」には別の意味もあります。変数宣言の前に置くと、予約キーワードを変数名として使用できます。

例えば:

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

これについては、正当な用途が1つまたは2つしか見つかりませんでした。主に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>

それ以外の場合は、予約済みのキーワードではない「クラス」を使用する必要がありますが、大文字の「C」はHTML標準に準拠しておらず、正しく見えません。


18

VBも明示的に要求したので、この逐語的文字列構文はVBには存在せず、C#にのみ存在することを付け加えます。むしろ、すべての文字列はVBでは逐語的です(C#の逐語的文字列とは異なり、改行を含めることができないという事実を除きます)。

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

エスケープシーケンスはVBには存在せず(C#の逐語的文字列のように引用符文字が2倍になることを除いて)、いくつかのことがより複雑になります。たとえば、VBで次のコードを書くには、連結(または文字列を構築する他の方法)を使用する必要があります。

string x = "Foo\nbar";

VBでは、次のように記述します。

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

&はVB文字列連結演算子です。+同じように使用できます。)


1
ああ、それは面倒そうに聞こえます...私が今C#を使用していることをさらにうれしく思います:p
Svish

C#の逐語的文字列リテラルには挿入できますが、VB文字列リテラルに改行を埋め込むことはできません。したがって、それらは同じではありません。
Joey、

@Svish、待って私は何かを逃していますか?これはVBの欠点ではありません。実際、これはVBがC#を獲得する1つの場所です。それは、このようにそれを行う方が良いでしょうし、明示的に改行し、代わりの間のすべての特殊文字投げの特殊文字連結"とを"
Pacerier 2015

@Pacerierそれはナンセンスです。些細な文字列処理以上のことを行うとすぐに、適切な文字列構築機能が不可欠になり、特殊文字を簡潔に処理する機能がこれらの中で最も重要になります。ただし、C#とVBの両方にがあるためString.Format、これを行うことができます。実際、私は今では決して書くこと"x" & Environment.NewLineはせず、代わりに常にString.Format("x{0}", Environment.Newline)使用します。それでも、ここではC#の方が便利です。
Konrad Rudolph、

@KonradRudolph、私は"x" & nl & nlまたは"x" + nl + nlまたは"x" . $nl . $nlいずれかの日を選択します"x\n\n"。また"x" + bs + bs 以上"x\\\\"。そして"x" + q + q以上"x\"\""/ "x"""""。ここで、についてはString.Format、上記で行っている比較とは無関係の別の問題です。
Pacerier 2015

10

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

C#は、通常の文字列リテラルと逐語的文字列リテラルの2つの形式の文字列リテラルをサポートしています。

通常の文字列リテラルは、「hello」のように、二重引用符で囲まれた0個以上の文字で構成され、単純なエスケープシーケンス(タブ文字の\ tなど)と16進数およびUnicodeエスケープシーケンスの両方を含めることができます。

逐語的文字列リテラルは、@文字の後に二重引用符文字、0個以上の文字、および終了二重引用符文字が続く形式で構成されます。簡単な例は@ "hello"です。逐語的文字列リテラルでは、区切り文字の間の文字は逐語的に解釈されますが、唯一の例外は引用エスケープシーケンスです。特に、単純なエスケープシーケンスと16進数およびUnicodeのエスケープシーケンスは、逐語的文字列リテラルでは処理されません。逐語的文字列リテラルは複数行にまたがることがあります。


9

これは逐語的文字列であり、エスケープルールを変更します-現在エスケープされる唯一の文字は "、"にエスケープされます。これは特にファイルパスと正規表現に役立ちます:

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


あなたの例では、Marcの@が欠けていませんか?または、varを使用するときのデフォルトですか?少し混乱しています...
Dirk Vollmar、2009

1
OK-それは本当に、本当に奇妙です。編集者がそれらを食べたのだろうか?
Marc Gravell

9

MSDNからコピー:

コンパイル時に、逐語的文字列はすべて同じエスケープシーケンスを持つ通常の文字列に変換されます。したがって、デバッガーウォッチウィンドウで逐語的文字列を表示すると、ソースコードの逐語的バージョンではなく、コンパイラーによって追加されたエスケープ文字が表示されます。たとえば、逐語的文字列@"C:\files.txt"はウォッチウィンドウにとして表示され"C:\\files.txt"ます。


これは、Microsoftのドキュメントの典型的な誤解を招く部分です。上記は最終結果として正しいと述べていますが、根本的な真実は、C#の文字列が関連するバイトシーケンス(またはマルチバイト文字コード)に変換されることです。C#では、@ "..."または "..."を使用して、基になる文字列を表す2つの異なる方法を使用できます。デバッガーは常に「...」の方法を選択し、最初にどちらが使用されたかを判別できません。(\ nや ""などのエスケープシーケンスは、プログラミングと表示レベルの文字列表現にのみ関連し、基になる文字列には決して格納されません!)
MikeBeaton

8

@文字列の前にを置くと、特殊コードやエスケープ文字を使用しなくても、バックスラッシュや二重引用符などの特殊文字を使用できます。

だからあなたは書くことができます:

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

の代わりに:

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

3

説明は簡単です。文字列を表すには、がエスケープ文字であるため"string\"、コンパイラが必要です。代わりに使用すると、について忘れることができます。"string\\"\@"string\"\\

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.