string.Empty vs null. Bạn sử dụng cái nào?


84

Gần đây một đồng nghiệp tại nơi làm việc nói với tôi rằng không sử dụng string.Emptykhi thiết lập một biến chuỗi mà sử dụng nullvì nó gây ô nhiễm ngăn xếp?

Anh ấy nói đừng làm

string myString=string.Empty; nhưng làm string mystring=null;

Thật sự nó có ảnh hưởng sao? Tôi biết chuỗi là một đối tượng nên nó có ý nghĩa.

Tôi biết là một câu hỏi ngớ ngẩn nhưng quan điểm của bạn là gì?


1
Tôi không hoàn toàn chắc chắn tại sao bạn lại làm như vậy ... bạn có thể cung cấp thêm một chút mã mà bạn đang thảo luận làm ví dụ không?
thợ rèn

không có mã nào. Tôi đã yêu cầu đồng nghiệp của mình xem xét thứ gì đó mà tôi đang gỡ lỗi và anh ấy nói theo nguyên tắc chung "không sử dụng string.empty" hãy đặt nó thành null khi nó xuất hiện trên ngăn xếp. Cá nhân tôi luôn sử dụng string.Empty vì thời điểm nó xuất hiện được cho là thứ thích hợp để sử dụng hơn là "".
user712923


Ý tôi là ... string.Empty, ""nulltất cả đều là các giá trị không đổi, nhưng chúng đều đủ 'đơn giản' để tôi không thể hiểu tại sao bạn lại gán một giá trị cho một biến. Nếu bạn cần nắm bắt một outbiến, tại sao không sử dụng string myString;?
thợ rèn

8
Ngày nay, các lập luận về các chủ đề như thế này không tập trung vào khả năng đọc và ngữ nghĩa mà chỉ tập trung vào các tối ưu hóa vi mô vô lý là rất yếu. Sử dụng bất kỳ cái nào có nghĩa là đúng với ngữ cảnh nhất định của bạn. (ví dụ: Nếu bạn biết ai đó không có tên đệm, bạn sử dụng String.Empty; nếu bạn không biết ai đó có tên đệm hay không thì bạn sử dụng null). Sau đó, khi bạn đã hiểu đúng, hãy viết mã theo cách rõ ràng chính xác và dễ bảo trì.
jason

Câu trả lời:


110

nullEmptyrất khác nhau, và tôi không khuyên bạn nên tự ý chuyển đổi giữa chúng. Nhưng không có bất kỳ "chi phí" bổ sung nào, vì Emptylà một tham chiếu cố định duy nhất (bạn có thể sử dụng nó bất kỳ số lần nào).

Không có "ô nhiễm" trên ngăn xếp do ldsfld gây ra - mối quan tâm đó là .... điên rồ. Việc tải a nullđược cho là rẻ hơn một chút , nhưng có thể gây ra các ngoại lệ tham chiếu rỗng nếu bạn không cẩn thận trong việc kiểm tra giá trị.

Cá nhân, tôi không sử dụng ... Nếu tôi muốn một chuỗi trống, tôi sử dụng ""- đơn giản và rõ ràng. Interning có nghĩa là điều này cũng không có chi phí cho mỗi lần sử dụng.


Ở cấp IL, sự khác biệt ở đây giữa "" và Empty chỉ là ldstr so với ldsfld - nhưng cả hai đều cung cấp cùng một tham chiếu chuỗi được thực hiện đơn lẻ. Hơn nữa, trong các phiên bản .NET gần đây hơn, JIT đã đánh chặn trực tiếp chúng, tạo ra tham chiếu chuỗi trống mà không thực sự thực hiện tra cứu trường tĩnh. Về cơ bản, không có lý do chính xác để quan tâm theo cả hai cách, ngoại trừ khả năng đọc. Tôi chỉ sử dụng "".


5
@ user712923 nếu anh ấy quay lại với bất kỳ mối quan tâm cụ thể nào, tôi rất muốn nghe họ
Marc Gravell

4
@Marc: ASAIK "" tạo một đối tượng mà không phải là string.Empty .. hãy kiểm tra điều nàyđiều này . Nó có một cái gì đó để làm với hồ bơi tập chuỗi ....
Jalal đã nói vào


1
+1 để sử dụng ""thay vì mã soạn sẵn dài hơn sáu lần. Ai chủ trương điều vô nghĩa này ?! @Jalal Bài đăng của Brad Abrams đã lỗi thời nghiêm trọng và nếu trình biên dịch vẫn không tối ưu hóa hai mã đó để hoạt động giống nhau, thì thật xấu hổ cho Microsoft! Nhưng việc của chúng tôi không phải là sửa chữa công việc của họ. Và trên thực tế, chúng ta không cần phải: Trong liên kết thứ hai, Lasse (trong phần bình luận) đã so sánh các đầu ra lắp ráp của việc so sánh với một trong hai biến thể: chúng giống hệt nhau.
Konrad Rudolph

1
@Konrad: Một ví dụ là những gì đang xảy ra khi nối các chuỗi hằng số: lớp string sử dụng intern pool nên khi bạn tạo một chuỗi mới, lớp sẽ kiểm tra xem chuỗi đã có trong pool chưa và sau đó nếu chưa thêm nó vào pool .. Do đó khi ""nó sẽ tìm kiếm toàn bộ pool để kiểm tra xem nó đã ở đó hay chưa, và đó là cách khi sử dụng string.Empty;nó sẽ sử dụng giá trị được xác định trước đó và tìm kiếm sẽ không còn nữa. lớp học cũng hiển thị các phương thức này: string.Intern/IsInternedhãy kiểm tra điều này
Jalal Đã nói vào

34

Nó không 'gây ô nhiễm ngăn xếp', không có lý do kỹ thuật nào nhưng có sự khác biệt lớn giữa việc đặt một biến thành tham chiếu đến một đối tượng (ngay cả khi đó là một chuỗi rỗng) và null. Chúng không giống nhau và nên được sử dụng theo những cách khác nhau.

nullnên được sử dụng để biểu thị sự vắng mặt của dữ liệu, string.Empty(hoặc "") để chỉ ra sự hiện diện của dữ liệu, trên thực tế là một số văn bản trống. Có trường hợp cụ thể nào mà bạn không chắc điều gì là thích hợp nhất không?

Chỉnh sửa, thêm các ví dụ:

  • Bạn có thể sử dụng string.Emptylàm hậu tố mặc định cho tên của một người (ví dụ như hầu hết mọi người không có bằng tiến sĩ)

  • Bạn có thể sử dụng nulltùy chọn cấu hình không được chỉ định trong tệp cấu hình. Trong trường hợp này, string.Emptysẽ được sử dụng nếu có tùy chọn cấu hình, nhưng giá trị được định cấu hình mong muốn là một chuỗi trống.


Tôi chưa bao giờ nghĩ như vậy, tôi phải admit.Given những gì bạn vừa nói, làm bạn quan tâm để cung cấp cho tôi một example.I biết lời giải thích của bạn là tự giải thích nhưng vẫn ... thanks
user712923

2
Chà, lý do duy nhất để chọn cái này hay cái kia là dựa vào nơi bạn sẽ sử dụng nó. Tức là sử dụng string.Emptyhoặc ""khi bạn muốn sử dụng một chuỗi trống và nullkhi bạn muốn chỉ ra không có dữ liệu. Bạn có thể sử dụng string.Emptylàm hậu tố mặc định cho tên của một người (ví dụ: hầu hết mọi người không có Tiến sĩ) - và nullcho một tùy chọn cấu hình không được chỉ định trong tệp cấu hình. Trong trường hợp thứ hai đó, string.Emptysẽ được sử dụng nếu có tùy chọn cấu hình, nhưng giá trị được định cấu hình mong muốn là một chuỗi trống.
Kieren Johnstone,

@Kieren Johnstone, nếu một người không có tên hậu tố, tại sao lại không dùng nullđể biểu thị "không có hậu tố"?
OfirD

8

Chúng khác nhau như những người khác đã trả lời.

static void Main(string[] args)
{
    string s1 = null;
    string s2 = string.Empty;
    string s3 = "";
    Console.WriteLine(s1 == s2);
    Console.WriteLine(s1 == s3);
    Console.WriteLine(s2 == s3);
}

 results:
 false     - since null is different from string.empty
 false     - since null is different from ""
 true      - since "" is same as string.empty

Vấn đề với việc quản lý chuỗi rỗng so với chuỗi null đang trở thành vấn đề khi bạn cần duy trì nó thành một tệp phẳng hoặc chuyển nó thông qua liên lạc, Vì vậy, tôi thấy nó có thể hữu ích cho những người truy cập trang này để đưa ra một giải pháp tốt cho vấn đề cụ thể đó.

Với mục đích lưu chuỗi thành tệp hoặc thông tin liên lạc:
bạn có thể muốn chuyển đổi chuỗi thành byte.
một phương pháp hay mà tôi khuyên bạn nên thêm là thêm 2 phân đoạn byte tiêu đề vào chuỗi đã chuyển đổi của bạn.

phân đoạn 1 - thông tin meta được lưu trữ trong 1 byte và mô tả độ dài của phân đoạn tiếp theo.

phân đoạn 2 - giữ độ dài của chuỗi được lưu.

ví dụ:
string "abcd" - để đơn giản hóa, tôi sẽ chuyển đổi nó bằng cách sử dụng bộ mã hóa ASCII và sẽ nhận được {65,66,67,68}.
tính toán phân đoạn 2 sẽ cho kết quả 4 - vì vậy 4 byte là độ dài của chuỗi được chuyển đổi.
tính toán phân đoạn 1 sẽ mang lại kết quả 1 - vì chỉ 1 byte được sử dụng để giữ thông tin độ dài của thông tin chuỗi được chuyển đổi (là 4, tức là nếu nó là 260, tôi sẽ nhận được 2)

Dải byte mới bây giờ sẽ là {1,4,65,66,67,68} có thể được lưu vào một tệp.

Lợi ích liên quan đến chủ đề là nếu tôi có một chuỗi trống để lưu, tôi sẽ nhận được từ chuyển đổi một mảng byte trống có độ dài bằng 0 và sau khi tính toán các phân đoạn, tôi sẽ có {1,0} có thể là được lưu và sau đó được tải và diễn giải lại thành một chuỗi trống. Mặt khác, nếu tôi có giá trị null trong chuỗi của mình, tôi sẽ chỉ có {0} làm mảng byte của tôi để lưu và một lần nữa khi được tải có thể được diễn giải trở lại null.

Có nhiều lợi ích hơn như biết kích thước được tải hoặc tích lũy nếu bạn ghép nhiều chuỗi.

Quay lại chủ đề - nó sẽ .. loại ô nhiễm ngăn xếp vì các nguyên tắc tương tự được mô tả đang được sử dụng bởi bất kỳ hệ thống nào để phân biệt null với rỗng .. vì vậy có chuỗi. Empty chiếm nhiều bộ nhớ hơn null, mặc dù tôi sẽ không gọi nó là ô nhiễm .. nó chỉ là 1 byte nữa.


1

Nó đã được trả lời là chết, nhưng null có nghĩa là không có giá trị, không được khởi tạo. string.Empty có nghĩa là "" (một chuỗi trống) như được nêu trên MSDN.

Cách an toàn nhất để kiểm tra chuỗi rỗng hoặc rỗng là sử dụng string.IsNullOrEmpty.


-2

FWIW, tôi thấy rằng trộn ""String.Emptykhông hoạt động:

var a = "";
alert("a " + (a == "") + ", " + (a==String.Empty));   //Yields "a true, false"

var b = String.Empty;
alert("b " + (b == "") + ", " + (b == String.Empty)); //Yields "b false, true"

Đặc biệt, nếu bạn sử dụng $.trimđể lấy giá trị của trường đầu vào DOM trống, sau đó so sánh nó với String.Empty, bạn nhận được false. Không chắc tại sao lại như vậy, nhưng bạn hiểu rồi. Bây giờ tôi chỉ cần sử dụng ""ở mọi nơi cho nhất quán.


1
Đúng. Đây là lý do tại sao tất cả chúng ta nên duy trì thói quen kiểm tra .Length==0hoặc sử dụng.Compare()
zanlok

14
Câu hỏi này hỏi về c # không js
Cole Johnson
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.