Điểm của thuộc tính string.Empty là gì


35

Tại sao tài sản được string foo = string.Emptybao gồm trong BCL? Có vẻ dài dòng hơn và không rõ ràng hơn việc chỉ sử dụng một chuỗi rỗng ( string foo = "")


6
Nitpick: Nó không phải là một phần của ngôn ngữ. Nó là một phần của BCL. VB.NET và F # có thể sử dụng nó, cũng như mọi ngôn ngữ .NET khác.
Oded

19
Bởi vì nếu không, bạn không thể làm những điều xấu xa như typeof(string).GetField("Empty").SetValue(null, " ");;)
Mason Wheeler

1
@MasonWheeler - Niềm vui của sự suy tư. Đối với cái ác thực sự, bạn cần phải hướng nội, nhỉ?
Oded

1
@MasonWheeler, +1. Trời ơi, kính bảo hộ, họ chẳng làm gì cả!]
Machado

1
@MasonWheeler Đó là tà ác, chắt lọc. Tôi thích điều này. Câu hỏi nếu bạn quan tâm: sẽ không an toàn hơn (và thực hiện đúng cách) để viết nó thành public static string Empty { get { return string.Intern(""); } }?
Jesse C. Choper

Câu trả lời:


55

Tôi chỉ có thể giả định ở đây:

string.Emptyđã được xác định cho nhân chứng - khi khởi tạo một chuỗi, có thể không rõ ràng từ ngữ cảnh ""thực sự có nghĩa rõ ràng là một công cụ khởi tạo (thay vì nullhoặc nói " "hoặc chỉ là một người giữ chỗ trong khi thử nghiệm). Sử dụng string.Emptylà một câu trả lời chắc chắn cho loại câu hỏi hóc búa đó.

Nó cũng có thể là một sự trở lại với C - một chuỗi trống trong C không phải là một chuỗi trống. Đó là một mảng ký tự có ký tự đầu tiên là null (do đó, trống), không giống với C #. Quan điểm của tôi ở đây là trong các ngôn ngữ khác nhau, bạn sẽ biểu diễn một chuỗi rỗng theo các cách khác nhau (và chúng có thể có ý nghĩa khác nhau) - có một string.Emptysự mơ hồ như vậy.

Trái ngược với những gì người khác nói về nhiều đối tượng - đây không phải là vấn đề vì bất kỳ chuỗi ký tự nào cũng sẽ được thực hiện trong quá trình biên dịch. Điều này bao gồm giá trị của string.Empty- "". Bất cứ khi nào một trong hai được lặp lại trong mã, đối tượng sẽ được lấy từ nhóm thực tập. Điều này đúng với mỗi miền ứng dụng .


5
+1 là câu trả lời đúng duy nhất cho đến nay.
psr

Một số ngôn ngữ thậm chí có thể không một chuỗi ký tự trống. Rõ ràng, Pascal tiêu chuẩn đã không.
dan04

2
"một chuỗi rỗng trong C không phải là một chuỗi rỗng" - nhưng, nếu bạn viết "", bạn sẽ nhận được {'\0'}, do đó, sẽ không có sự khác biệt giữa một chuỗi ký tự trống và một số cách xác định đường vòng khác.
gièm pha

14

Tôi không chắc chắn 100% về các nguồn mà tôi đã học được những điều này, nhưng một số điểm để sử dụng nó bao gồm:

  • Mỗi chuỗi trong một cụm .NET là duy nhất, do đó, có

    string foo = "";
    string bar = "";

    kết quả là 2 chuỗi trong tập hợp đầu ra vì các chuỗi là bất biến. Có cả tham chiếu string.Emptylàm giảm kích thước lắp ráp.

  • Nhân chứng. Khi bạn bắt gặp string.Emptyý định rõ ràng rằng nó được coi là một chuỗi trống. Nhưng nếu bạn đi qua foo = "", lập trình viên đã loại bỏ nội dung của chuỗi trong khi kiểm tra và quên thêm nó trở lại, hay nó được cho là như vậy?

1
Nó dường như là một hành vi kỳ lạ đối với nó để giữ hai chuỗi giống hệt nhau trong bộ nhớ. Đó là trong thực tế những gì được thực hiện?
Giàn khoan

36
Trong thực tế, điều ngược lại đã được thực hiện - nó được gọi là thực tập chuỗi (chính xác hơn là thực tập theo nghĩa đen). Tôi biết chắc chắn rằng nó được thực hiện bằng Java và Python và tôi cũng chắc chắn rằng đó cũng là trường hợp của ngôn ngữ .NET. Tất nhiên, nó chỉ có thể xảy ra ở phạm vi của một đơn vị dịch thuật, vì vậy trừ khi trình tải động thống nhất dữ liệu đó, bạn có thể kết thúc bằng một chuỗi trống cho mỗi tệp chương trình. Vẫn không quá nhiều.

9
@delnan hoàn toàn đúng. ""/ string.Emptyđược thực tập và chỉ có một đối tượng sẽ được tạo.
Oded

11
@Andy - Tất cả các chuỗi ký tự được tập trung vào .NET. Không phải tất cả các chuỗi. Các chuỗi được tạo theo lập trình không được mặc định theo mặc định. Xem String.Itern trên MSDN.
Oded

3
@Oded et alia: Thật ra không ai trong số bạn hoàn toàn đúng. Đầu tiên, nghĩa đen được tập trung trong một hội đồng nhưng không nhất thiết phải qua các hội đồng . Thứ hai, có hay không chuỗi trống được tập trung trên các cụm là một chi tiết triển khai; một số phiên bản của CLR làm và một số thì không. Có một liên kết đến bài viết của tôi về thực tế này trong một trong những câu trả lời khác; xem nó để biết chi tiết
Eric Lippert

2

Không có đối tượng sẽ được tạo ra cho string.Empty. Việc sử dụng ""sẽ tạo ra một đối tượng rất có thể sẽ đến từ nhóm thực tập chuỗi.

Trước đây, mọi người đã chạy thử nghiệm và String.Emptyra mắt nhanh hơn một chút, nhưng đó là một tối ưu hóa vi mô.

String.Empty là đây:

//The Empty constant holds the empty string value.   
//We need to call the String constructor so that the compiler doesn't mark 
//this as a literal.   
//Marking this as a literal would mean that it doesn't show up as a field 
//which we can access from native.  
public static readonly String Empty = ""; 

2
Vậy quan điểm của bạn là ...?

1
Vấn đề là String.Empty về cơ bản là một hằng số cho "". Tìm tác giả của String.cs cho ý nghĩa sâu sắc hơn. :)
Jon Raynor

0

Đó là vấn đề tối ưu hóa mức tiêu thụ bộ nhớ và tối ưu hóa so sánh chuỗi. Mỗi khi bạn sử dụng một chuỗi trống trong ứng dụng của mình, bạn sẽ phân bổ một đối tượng chuỗi chứa 0 ký tự. Đối với so sánh chuỗi, nó có thể được thực hiện bằng cách so sánh các tham chiếu (con trỏ) thay vì ký tự theo từng ký tự, nhanh hơn ngay cả đối với các chuỗi trống.

Nếu bạn đang sử dụng nhiều lần cùng một chuỗi trong ứng dụng của mình, bạn có thể sử dụng cùng loại cơ chế bằng cách gọi String.I INTERN () với chuỗi của bạn. Nhưng nếu bạn chỉ sử dụng mỗi chuỗi một lần, thì bạn sẽ chỉ sử dụng thêm bộ nhớ.

Vì vậy, String.Empty chỉ là một tối ưu hóa trường hợp đặc biệt đáng để thực hiện đối với hầu hết các ứng dụng .Net, đó là lý do tại sao nó được tích hợp trong BCL.

Để biết thêm chi tiết về chủ đề này, tôi thực sự khuyên bạn nên đọc bài đăng trên blog của Eric Lippert .

Bạn cũng nên xem tài liệu này được tham khảo bởi bài viết trên blog của anh ấy.


4
Liên kết chỉ trả lời không làm cho câu trả lời tốt. Nếu Eric tổ chức lại blog của mình, câu trả lời này sẽ trở nên vô dụng. Hãy tóm tắt bài viết ở đây để chúng tôi có tất cả các thông tin trong tay.
ChrisF

7
@ChrisF: Tôi không thể tổ chức lại blog. Đó sẽ là một sự thay đổi đột phá, và bạn biết tôi cảm thấy thế nào về những điều đó.
Eric Lippert

1
@EricLippert - Tôi nhận ra rằng bạn sẽ không bao giờ làm điều đó, tuy nhiên, chỉ liên kết câu trả lời không phải là câu trả lời hay và chúng tôi cần khuyến khích mọi người nhận ra điều đó.
ChrisF

3
@EricLippert Không chỉ là về các liên kết phù du. Đây cũng là về sự lịch sự với độc giả ở đây, nên có ít nhất đủ nội dung trực tiếp trong câu trả lời để người đọc có thể đưa ra ý kiến ​​về việc có nên theo liên kết hay không. Và câu trả lời sẽ có ý nghĩa ngay cả trong một bản sao ngoại tuyến của SE.
Gilles 'SO- ngừng trở nên xấu xa'
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.