Apa @ di depan string di C #?

604

Ini adalah pertanyaan .NET untuk C # (atau mungkin VB.net), tetapi saya mencoba mencari tahu apa perbedaan antara deklarasi berikut:

string hello = "hello";

vs.

string hello_alias = @"hello";

Mencetak pada konsol tidak ada bedanya, properti panjangnya sama.

Klaw
sumber
Silakan lihat (dan ingatkan) saran saya untuk Visual Studio IDE untuk pemformatan string kata demi kata yang lebih baik: Indent multi-line string kata demi kata .
Olivier Jacot-Descombes
Agar jelas, contoh-contoh di atas menghasilkan hasil yang persis sama dengan atau tanpa @.
Miro J.

Jawaban:

768

Ini menandai string sebagai string kata demi kata - apa pun dalam string yang biasanya ditafsirkan sebagai urutan pelarian diabaikan.

Begitu "C:\\Users\\Rich"juga dengan@"C:\Users\Rich"

Ada satu pengecualian: urutan pelarian diperlukan untuk kutipan ganda. Untuk menghindari kutip ganda, Anda harus menempatkan dua kutip ganda berturut-turut. Misalnya, @""""evaluasi ke ".

Richard Ev
sumber
1
@RichardEverett Saya mengerti jawabannya, Tapi keraguan saya adalah apa sebenarnya penggunaan fitur ini?
Arun
24
@Arun Ini benar-benar berguna ketika berhadapan dengan string yang berisi hal-hal seperti definisi ekspresi reguler yang sering membutuhkan sesuatu untuk melarikan diri sendiri
James Thorpe
25
+ konten multi-baris
Jaider
4
Anda juga masih harus menggandakan kawat gigi {{jika Anda ingin menggunakan penjepit biasa dalam string.Formatpanggilan.
Dave Cousineau
4
@RichardEverett sangat berguna untuk membuat multi-string string literal tanpa harus memecah baris menjadi potongan-potongan.
John Mott
256

Ini adalah string literal kata demi kata . Ini berarti melarikan diri tidak berlaku. Contohnya:

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

Di sini verbatimdan regularmemiliki konten yang sama.

Ini juga memungkinkan konten multi-line - yang bisa sangat berguna untuk SQL:

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

Satu-satunya jalan keluar yang diperlukan untuk string literal kata demi kata adalah untuk mendapatkan tanda kutip ganda (") yang Anda lakukan dengan menggandakannya:

string verbatim = @"He said, ""Would you like some coffee?"" and left.";
string regular = "He said, \"Would you like some coffee?\" and left.";
Jon Skeet
sumber
16
Itu juga memungkinkan menggunakan kata-kata yang dicadangkan sebagai nama dan barang variabel. Seperti GetValueOrDefault publik (int @default);
Svish
5
Svish: Benar tetapi tidak terkait dengan pertanyaan khusus ini.
Jon Skeet
63

'@' Juga memiliki arti lain: meletakkannya di depan deklarasi variabel memungkinkan Anda untuk menggunakan kata kunci yang dipesan sebagai nama variabel.

Sebagai contoh:

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

Saya hanya menemukan satu atau dua kegunaan yang sah untuk ini. Terutama di ASP.NET MVC ketika Anda ingin melakukan sesuatu seperti ini:

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

Yang akan menghasilkan tautan HTML seperti:

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

Kalau tidak, Anda harus menggunakan 'Kelas', yang bukan kata kunci yang dicadangkan tetapi huruf besar 'C' tidak mengikuti standar HTML dan tidak terlihat benar.

JulianR
sumber
18

Karena Anda secara eksplisit meminta VB juga, izinkan saya menambahkan saja sintaks string kata demi kata ini tidak ada di VB, hanya di C #. Sebaliknya, semua string adalah kata demi kata dalam VB (kecuali untuk fakta bahwa mereka tidak dapat berisi jeda baris, tidak seperti string C # verbatim):

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

Escape sequence tidak ada di VB (kecuali penggandaan karakter kutipan, seperti dalam string C # verbatim) yang membuat beberapa hal lebih rumit. Misalnya, untuk menulis kode berikut dalam VB Anda harus menggunakan gabungan (atau cara lain untuk membangun string)

string x = "Foo\nbar";

Dalam VB ini akan ditulis sebagai berikut:

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

( &adalah operator rangkaian string VB. +dapat juga digunakan.)

Konrad Rudolph
sumber
1
Ya ampun, itu terdengar mengganggu ... bahkan lebih senang saya menggunakan C # sekarang: p
Svish
Anda tidak dapat menanamkan pemisah baris ke dalam literal string VB, meskipun Anda bisa ke dalam string literal kata kunci C #. Jadi mereka tidak sama.
Joey
@Vish, Tunggu, apakah saya melewatkan sesuatu? Ini bukan tipuan untuk VB sama sekali. Memang ini adalah satu tempat di mana VB memenangkan C #. Lebih baik melakukannya dengan cara ini dan secara eksplisit menyatukan baris baru dan karakter khusus daripada membuang semua karakter khusus di antara" dan ".
Pacerier
@Pacerier Itu omong kosong. Segera setelah Anda melakukan lebih dari sekadar pemrosesan string sepele, fasilitas pembuatan string yang tepat sangat diperlukan, dan kemampuan menangani karakter khusus secara ringkas adalah yang terpenting di antaranya. Namun, baik C # dan VB miliki String.Format, yang memungkinkan melakukan ini. Bahkan, sekarang saya tidak akan pernah menulis "x" & Environment.NewLine, dan sebagai gantinya selalu menggunakan String.Format("x{0}", Environment.Newline)dll. Namun, C # lebih nyaman di sini.
Konrad Rudolph
@KonradRudolph, aku akan memilih "x" & nl & nlatau "x" + nl + nlatau "x" . $nl . $nlsetiap hari selama "x\n\n". Juga sudah "x" + bs + bs berakhir "x\\\\". Dan"x" + q + q lebih dari "x\"\""/ "x""""". Sekarang String.Format, itu masalah lain yang tidak terkait dengan perbandingan yang kami lakukan di atas.
Pacerier
10

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

C # mendukung dua bentuk string literal: string literal biasa dan string literal kata demi kata.

Literal string reguler terdiri dari nol atau lebih karakter yang diapit dengan tanda kutip ganda, seperti dalam "halo", dan dapat mencakup urutan escape sederhana (seperti \ untuk karakter tab) dan urutan escape hexadecimal dan Unicode.

Literal string kata demi kata terdiri dari karakter @ diikuti oleh karakter kutipan ganda, nol atau lebih karakter, dan karakter kutipan ganda penutup. Contoh sederhana adalah @ "halo". Dalam string literal kata demi kata, karakter di antara pembatas diinterpretasikan secara verbatim, satu-satunya pengecualian adalah urutan kutipan-escape. Secara khusus, sekuens escape sederhana dan sekuens heksadesimal dan Unicode tidak diproses dalam string literal kata demi kata. Sebuah string literal kata demi kata dapat menjangkau beberapa baris.

Ed Guinness
sumber
9

Ini adalah string kata demi kata, dan mengubah aturan pelolosan - satu-satunya karakter yang sekarang diloloskan adalah ", lolos ke" ". Ini sangat berguna untuk jalur file dan regex:

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

dll

Marc Gravell
sumber
Apakah Anda tidak kehilangan @ dalam contoh Anda, Marc? Atau apakah itu default ketika saya menggunakan var? Agak bingung ...
Dirk Vollmar
1
OK - itu benar-benar aneh. Saya ingin tahu apakah editor mengunyah mereka?
Marc Gravell
9

Disalin dari MSDN :

Pada waktu kompilasi, string kata demi kata dikonversi menjadi string biasa dengan semua urutan pelarian yang sama. Oleh karena itu, jika Anda melihat string kata demi kata di jendela arloji debugger, Anda akan melihat karakter pelarian yang ditambahkan oleh kompiler, bukan versi verbatim dari kode sumber Anda. Sebagai contoh, string kata demi kata @"C:\files.txt"akan muncul di jendela arloji sebagai "C:\\files.txt".

aanund
sumber
Yang merupakan tipikal dokumentasi Microsoft yang menyesatkan, IMHO! Apa yang dinyatakan di atas sebagai hasil akhir adalah benar, tetapi kebenaran mendasarnya adalah bahwa string dalam C # dikonversi ke urutan byte yang relevan (atau kode karakter multi-byte). C # memungkinkan dua cara berbeda untuk mewakili string yang mendasarinya, dengan @ "..." atau "...". Debugger selalu memilih cara "...", dan tidak bisa membedakan mana yang digunakan. (Urutan melarikan diri seperti \ n atau "" hanya relevan untuk pemrograman dan representasi string tingkat tampilan, dan tidak pernah disimpan dalam string yang mendasarinya!)
MikeBeaton
8

Puting a @ di depan string memungkinkan Anda untuk menggunakan karakter khusus seperti garis miring terbalik atau tanda kutip ganda tanpa harus menggunakan kode khusus atau karakter melarikan diri.

Jadi, Anda dapat menulis:

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

dari pada:

string path = "C:\\My path\\";
Presidenten
sumber
3

Penjelasannya sederhana. Untuk mewakili string "string\", kompiler perlu "string\\"karena \merupakan karakter pelarian. Jika Anda menggunakannya @"string\", Anda bisa melupakannya \\.

Ray Wu
sumber