หน้า @ ของสตริงใน C # คืออะไร?


603

นี่คือคำถาม. NET สำหรับ C # (หรืออาจเป็น VB.net) แต่ฉันพยายามที่จะเข้าใจว่าอะไรคือความแตกต่างระหว่างการประกาศต่อไปนี้:

string hello = "hello";

เมื่อเทียบกับ

string hello_alias = @"hello";

การพิมพ์บนคอนโซลไม่สร้างความแตกต่างคุณสมบัติความยาวจะเหมือนกัน


โปรดดู (และ upvote) คำแนะนำของฉันสำหรับ Visual Studio IDE สตริงคำต่อคำที่ดีกว่าการจัดรูปแบบ: เยื้องหลายสายสตริงคำต่อคำ
Olivier Jacot-Descombes

@ต้องมีความชัดเจนตัวอย่างข้างต้นมีการผลิตว่าผลเดียวกันด้วยหรือไม่
Miro J.

คำตอบ:


767

มันทำเครื่องหมายสตริงเป็นตัวอักษรคำต่อคำสตริง - สิ่งใดในสตริงที่ปกติจะถูกตีความว่าเป็นลำดับหนีจะถูกละเว้น

ดังนั้น"C:\\Users\\Rich"เป็นเช่นเดียวกับ@"C:\Users\Rich"

มีข้อยกเว้นหนึ่งประการ: จำเป็นต้องมีลำดับการหลบหนีสำหรับเครื่องหมายคำพูดคู่ ในการหลีกเลี่ยงอัญประกาศคุณต้องใส่เครื่องหมายคำพูดคู่สองตัวในหนึ่งแถว ยกตัวอย่างเช่นประเมิน@"""""


1
@ RichardEverett ฉันเข้าใจคำตอบ แต่สิ่งที่ฉันสงสัยคือการใช้คุณสมบัตินี้คืออะไร?
อรุณ

24
@Arun มันมีประโยชน์จริงๆเมื่อต้องรับมือกับสตริงที่มีสิ่งที่ต้องการคำจำกัดความนิพจน์ปกติที่มักจะต้องสิ่งที่จะหนีตัวเอง
เจมส์ ธ อร์ป

25
+ เนื้อหาหลายบรรทัด
Jaider

4
คุณยังจะต้องจัดฟันสองครั้ง{{หากคุณต้องการใช้เครื่องมือจัดฟันแบบปกติในการstring.Formatโทร
Dave Cousineau

4
@RichardEverett มันมีประโยชน์มากสำหรับการสร้างตัวอักษรสตริงหลายบรรทัดโดยไม่ต้องแบ่งบรรทัดออกเป็นชิ้น ๆ
John Mott

256

มันเป็นตัวอักษรสตริงคำต่อคำ หมายความว่าไม่ได้ใช้การหลบหนี ตัวอย่างเช่น

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.";

16
นอกจากนี้ยังอนุญาตให้ใช้คำสงวนเป็นชื่อตัวแปรและสิ่งต่างๆ ชอบสาธารณะ int GetValueOrDefault (int @default);
Svish

5
Svish: จริง แต่ไม่เกี่ยวข้องกับคำถามนี้
Jon Skeet

63

'@' มีความหมายอื่นเช่นกัน: การใส่ไว้ข้างหน้าประกาศตัวแปรช่วยให้คุณใช้คำหลักที่สงวนไว้เป็นชื่อตัวแปร

ตัวอย่างเช่น:

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>

มิฉะนั้นคุณจะต้องใช้ 'คลาส' ซึ่งไม่ใช่คำหลักที่สงวนไว้ แต่ตัวพิมพ์ใหญ่ 'C' ไม่เป็นไปตามมาตรฐาน HTML และดูไม่ถูกต้อง


18

เมื่อคุณถาม VB ด้วยเช่นกันขอผมเพิ่มหน่อยว่าไวยากรณ์สตริงคำต่อคำนี้ไม่มีอยู่ใน VB เฉพาะใน C # ค่อนข้างสตริงทั้งหมดเป็นคำต่อคำใน VB (ยกเว้นความจริงที่ว่าพวกเขาไม่สามารถมีตัวแบ่งบรรทัดซึ่งแตกต่างจากสตริง C # verbatim):

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

Escape sequences ไม่มีอยู่ใน VB (ยกเว้นการเพิ่มตัวอักษรอัญประกาศเป็นสองเท่าเช่นในสตริง C # verbatim) ซึ่งทำให้บางสิ่งซับซ้อนมากขึ้น ตัวอย่างเช่นในการเขียนโค้ดต่อไปนี้ใน VB คุณต้องใช้การต่อข้อมูล (หรือวิธีอื่นใดในการสร้างสตริง)

string x = "Foo\nbar";

ใน VB นี้จะถูกเขียนดังนี้:

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

( &เป็นตัวดำเนินการเรียงต่อสตริง VB +สามารถใช้งานได้อย่างเท่าเทียมกัน)


1
โอ้ฉันฟังดูน่ารำคาญ ... ยิ่งดีใจที่ฉันใช้ C # ตอนนี้: p
Svish

คุณไม่สามารถฝังตัวแบ่งบรรทัดลงในตัวอักษรสตริง VB ได้แม้ว่าคุณจะสามารถใส่ตัวอักษรสตริงแบบคำต่อคำของ C # ได้ พวกเขาไม่เหมือนกัน
Joey

@Svish รอฉันหายไปบางอย่าง? นี่ไม่ใช่การแย้งสำหรับ VB เลย อันที่จริงนี่คือที่เดียวที่ VB ชนะ C # มันจะดีกว่าที่จะทำมันด้วยวิธีนี้และชัดเจน concat การขึ้นบรรทัดใหม่และตัวอักษรพิเศษแทนการขว้างปาทุกตัวอักษรพิเศษระหว่างและ" "
Pacerier

@Pierier นั่นเป็นเรื่องไร้สาระ ทันทีที่คุณทำมากกว่าการประมวลผลสายเล็ก ๆ สิ่งอำนวยความสะดวกในการสร้างสายอักขระที่เหมาะสมนั้นขาดไม่ได้และความสามารถในการจัดการอักขระพิเศษอย่างรัดกุมนั้นเป็นสิ่งสำคัญที่สุด อย่างไรก็ตามทั้ง 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

10

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

C # รองรับสองรูปแบบของตัวอักษรสตริง: ตัวอักษรสตริงปกติและตัวอักษรสตริงคำต่อคำ

สตริงตัวอักษรปกติประกอบด้วยอักขระศูนย์หรือมากกว่าที่อยู่ในเครื่องหมายคำพูดคู่เช่นเดียวกับใน "hello" และอาจรวมทั้ง escape sequences แบบง่าย (เช่น \ t สำหรับอักขระแท็บ) และลำดับเลขฐานสิบหกและ Unicode

สตริงตัวอักษร verbatim ประกอบด้วยอักขระ @ ตามด้วยอักขระเครื่องหมายคำพูดคู่, ศูนย์หรือมากกว่าอักขระและอักขระเครื่องหมายคำพูดคู่ปิด ตัวอย่างง่ายๆคือ @ "hello" ในสตริงตัวอักษรคำต่อคำตัวอักษรระหว่างตัวคั่นจะถูกแปลเป็นคำต่อคำยกเว้นเพียงข้อเดียวคือ โดยเฉพาะอย่างยิ่ง escape sequences อย่างง่ายและ hexadecimal และ Unicode escape sequences ไม่ถูกประมวลผลในตัวอักษรสตริง verbatim สตริงตัวอักษรคำต่อคำอาจขยายหลายบรรทัด


9

นี่เป็นสตริงคำต่อคำและเปลี่ยนกฎการหลบหลีก - ตัวอักษรเดียวที่หนีออกมาในขณะนี้คือ ", escaped เป็น" "ซึ่งเป็นประโยชน์อย่างยิ่งสำหรับพา ธ ไฟล์และ regex:

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

ฯลฯ


คุณไม่ได้ใช้เครื่องหมาย @ ในตัวอย่างของคุณมาร์ค? หรือเป็นค่าเริ่มต้นเมื่อฉันใช้ var? สับสนเล็กน้อย ...
Dirk Vollmar

1
ตกลง - มันแปลกจริง ๆ ฉันสงสัยว่าตัวแก้ไขมันเคี้ยวแล้วหรือยัง?
Marc Gravell

9

คัดลอกมาจากMSDN :

ณ เวลารวบรวมสตริง verbatim จะถูกแปลงเป็นสตริงสามัญที่มีลำดับ escape เดียวกันทั้งหมด ดังนั้นหากคุณดูสตริงคำต่อคำในหน้าต่างดูการดีบักเกอร์คุณจะเห็นอักขระเลี่ยงที่เพิ่มโดยคอมไพเลอร์ไม่ใช่เวอร์ชันคำต่อคำจากซอร์สโค้ดของคุณ ยกตัวอย่างเช่นสตริงคำต่อคำจะปรากฏในหน้าต่างดูเป็น@"C:\files.txt""C:\\files.txt"


ข้อผิดพลาดทั่วไปของเอกสาร Microsoft ซึ่งเป็น IMHO! สิ่งที่ระบุไว้ข้างต้นในฐานะผลลัพธ์สุดท้ายนั้นถูกต้อง แต่ความจริงที่สำคัญคือสตริงใน C # จะถูกแปลงเป็นลำดับไบต์ที่เกี่ยวข้อง (หรือรหัสอักขระหลายไบต์) C # อนุญาตให้มีสองวิธีที่แตกต่างกันในการแสดงสตริงพื้นฐานโดยมี @ "... " หรือ "... " ตัวดีบักเลือกวิธี "... " เสมอและไม่สามารถบอกได้ว่าจะใช้วิธีใดในตอนแรก (Escape sequences เช่น \ 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.