@ Ở trước chuỗi trong C # là gì?


604

Đây là một câu hỏi .NET cho C # (hoặc có thể là VB.net), nhưng tôi đang cố gắng tìm ra sự khác biệt giữa các khai báo sau:

string hello = "hello";

so với

string hello_alias = @"hello";

In ra trên bàn điều khiển không có sự khác biệt, các thuộc tính chiều dài là như nhau.


Vui lòng xem (và upvote) đề xuất của tôi cho Visual Studio IDE để định dạng chuỗi nguyên văn tốt hơn: Chuỗi nguyên văn nhiều dòng thụt lề .
Olivier Jacot-Descombes

Để rõ ràng, các ví dụ trên đang tạo ra kết quả chính xác như nhau có hoặc không có @.
Miro J.

Câu trả lời:


768

Nó đánh dấu chuỗi là một chuỗi nguyên văn - bất kỳ thứ gì trong chuỗi thường được hiểu là một chuỗi thoát đều bị bỏ qua.

Vì vậy, "C:\\Users\\Rich"cũng giống như@"C:\Users\Rich"

Có một ngoại lệ: một chuỗi thoát là cần thiết cho trích dẫn kép. Để thoát một trích dẫn kép, bạn cần đặt hai dấu ngoặc kép liên tiếp. Ví dụ, @""""đánh giá để ".


1
@RichardEverett Tôi đã hiểu câu trả lời, nhưng nghi ngờ của tôi là việc sử dụng thực sự của tính năng này là gì?
Arun

24
@Arun Nó thực sự hữu ích khi xử lý các chuỗi có chứa những thứ như định nghĩa biểu thức chính quy thường cần những thứ phải tự thoát
James Thorpe

25
+ nội dung nhiều dòng
Jaider

4
bạn cũng sẽ vẫn phải tăng gấp đôi niềng răng {{nếu muốn sử dụng niềng răng thông thường trong string.Formatcuộc gọi.
Dave Cousineau

4
@RichardEverett nó rất hữu ích để tạo ra các chuỗi ký tự chuỗi nhiều dòng mà không phải chia dòng thành từng mảnh.
John Mott

256

Đó là một chuỗi nguyên văn . Nó có nghĩa là thoát không được áp dụng. Ví dụ:

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

Ở đây verbatimregularcó cùng nội dung.

Nó cũng cho phép nội dung nhiều dòng - có thể rất tiện cho SQL:

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

Một chút thoát cần thiết cho các chuỗi ký tự nguyên văn là lấy một trích dẫn kép (") mà bạn làm bằng cách nhân đôi nó:

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

16
Nó cũng cho phép sử dụng các từ dành riêng như tên biến và công cụ. Giống như công khai int GetValueOrDefault (int @default);
Svish

5
Svish: Đúng nhưng không liên quan đến câu hỏi cụ thể này.
Jon Skeet

63

Một '@' cũng có một ý nghĩa khác: đặt nó trước một khai báo biến cho phép bạn sử dụng các từ khóa dành riêng làm tên biến.

Ví dụ:

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

Tôi chỉ tìm thấy một hoặc hai cách sử dụng hợp pháp cho việc này. Chủ yếu trong ASP.NET MVC khi bạn muốn làm một cái gì đó như thế này:

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

Điều này sẽ tạo ra một liên kết HTML như:

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

Nếu không, bạn sẽ phải sử dụng 'Class', đây không phải là một từ khóa dành riêng nhưng chữ hoa 'C' không tuân theo các tiêu chuẩn HTML và trông không ổn.


18

Vì bạn cũng yêu cầu VB rõ ràng, hãy để tôi thêm rằng cú pháp chuỗi nguyên văn này không tồn tại trong VB, chỉ có trong C #. Thay vào đó, tất cả các chuỗi là nguyên văn trong VB (ngoại trừ thực tế là chúng không thể chứa các ngắt dòng, không giống như các chuỗi nguyên văn C #):

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

Các chuỗi thoát không tồn tại trong VB (ngoại trừ việc nhân đôi ký tự trích dẫn, như trong chuỗi nguyên văn C #) khiến cho một vài điều phức tạp hơn. Ví dụ, để viết mã sau đây trong VB, bạn cần sử dụng phép nối (hoặc bất kỳ cách nào khác để xây dựng chuỗi)

string x = "Foo\nbar";

Trong VB, điều này sẽ được viết như sau:

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

( &là toán tử nối chuỗi VB. +có thể được sử dụng như nhau.)


1
Ôi trời, nghe có vẻ khó chịu ... thậm chí còn vui hơn nữa khi tôi đang sử dụng C #: p
Svish

Bạn không thể nhúng các ngắt dòng vào các chuỗi ký tự chuỗi VB, mặc dù bạn có thể nhập các chuỗi ký tự nguyên văn của C #. Chúng không giống nhau.
Joey

@Svish, Chờ tôi có thiếu thứ gì không? Đây không phải là một con cho VB. Quả thực đây là một nơi mà VB thắng C #. Tốt hơn là làm theo cách này và kết hợp rõ ràng các dòng mới và các ký tự đặc biệt thay vì ném tất cả các ký tự đặc biệt giữa "".
Pacerier

@Pacerier Điều đó thật vớ vẩn. Ngay khi bạn làm nhiều hơn việc xử lý chuỗi tầm thường, các cơ sở xây dựng chuỗi thích hợp là không thể thiếu, và khả năng xử lý chính xác các ký tự đặc biệt là quan trọng nhất trong số này. Tuy nhiên, cả C # và VB đều có String.Format, cho phép thực hiện điều này. Trên thực tế, bây giờ tôi sẽ không bao giờ viết "x" & Environment.NewLine, và thay vào đó luôn luôn sử dụng, String.Format("x{0}", Environment.Newline)v.v. Tuy nhiên, C # thuận tiện hơn ở đây.
Konrad Rudolph

@KonradRudolph, tôi muốn chọn "x" & nl & nlhoặc "x" + nl + nlhoặc "x" . $nl . $nlbất cứ ngày qua "x\n\n". Cũng "x" + bs + bs hơn rồi "x\\\\". Và "x" + q + qhơn "x\"\""/ "x""""". Bây giờ String.Format, đối với , đó là một vấn đề khác không liên quan đến so sánh chúng tôi đang làm ở trên.
Pacerier

10

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

C # hỗ trợ hai dạng chuỗi ký tự chuỗi: chuỗi ký tự chuỗi thông thường và chuỗi ký tự chuỗi nguyên văn.

Một chuỗi ký tự thông thường bao gồm 0 hoặc nhiều ký tự được đặt trong dấu ngoặc kép, như trong "xin chào" và có thể bao gồm cả các chuỗi thoát đơn giản (chẳng hạn như \ t cho ký tự tab) và các chuỗi thoát hex và thập lục phân.

Một chuỗi ký tự nguyên văn bao gồm một ký tự @ theo sau là một ký tự trích dẫn kép, 0 hoặc nhiều ký tự và một ký tự trích dẫn kép đóng. Một ví dụ đơn giản là @ "xin chào". Trong một chuỗi nguyên văn theo nghĩa đen, các ký tự giữa các dấu phân cách được giải thích nguyên văn, ngoại lệ duy nhất là một chuỗi trích dẫn thoát. Cụ thể, các chuỗi thoát đơn giản và các chuỗi thoát thập lục phân và Unicode không được xử lý theo nghĩa đen của chuỗi. Một chuỗi nguyên văn có thể kéo dài nhiều dòng.


9

Đây là một chuỗi nguyên văn và thay đổi các quy tắc thoát - ký tự duy nhất hiện đang thoát là ", thoát thành" ". Điều này đặc biệt hữu ích cho đường dẫn tệp và biểu thức chính quy:

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

Vân vân


Bạn không bỏ lỡ ví dụ @ trong bạn à, Marc? Hoặc nó là mặc định khi tôi sử dụng var? Ít bối rối ...
Dirk Vollmar

1
OK - đó là thực sự, thực sự kỳ lạ. Tôi tự hỏi nếu biên tập viên nhai chúng?
Marc Gravell

9

Sao chép từ MSDN :

Tại thời điểm biên dịch, các chuỗi nguyên văn được chuyển đổi thành các chuỗi thông thường với tất cả các chuỗi thoát giống nhau. Do đó, nếu bạn xem một chuỗi nguyên văn trong cửa sổ xem trình gỡ lỗi, bạn sẽ thấy các ký tự thoát được trình biên dịch thêm vào, chứ không phải phiên bản nguyên văn từ mã nguồn của bạn. Ví dụ, chuỗi nguyên văn @"C:\files.txt"sẽ xuất hiện trong cửa sổ xem "C:\\files.txt".


Đó là một phần gây hiểu lầm điển hình của tài liệu Microsoft, IMHO! Những gì các trạng thái trên là kết quả cuối cùng là chính xác, nhưng sự thật cơ bản là các chuỗi trong C # được chuyển đổi thành chuỗi byte có liên quan (hoặc mã ký tự nhiều byte). C # cho phép hai cách khác nhau để biểu diễn chuỗi bên dưới, với @ "..." hoặc "...". Trình gỡ lỗi luôn chọn cách "..." và không thể biết được sử dụng ở vị trí đầu tiên. (Các chuỗi thoát như \ n hoặc "" chỉ liên quan đến lập trình và hiển thị chuỗi mức độ và không bao giờ được lưu trữ trong chuỗi bên dưới!)
MikeBeaton

8

Đặt một @ chuỗi phía trước một chuỗi cho phép bạn sử dụng các ký tự đặc biệt như dấu gạch chéo ngược hoặc dấu ngoặc kép mà không phải sử dụng mã đặc biệt hoặc ký tự thoát.

Vì vậy, bạn có thể viết:

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

thay vì:

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

3

Giải thích rất đơn giản. Để đại diện cho chuỗi "string\", trình biên dịch cần "string\\"\là một ký tự thoát. Nếu bạn sử dụng @"string\"thay thế, bạn có thể quên đi \\.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.