Không thể sử dụng String.Empty làm giá trị mặc định cho một tham số tùy chọn


89

Tôi đang đọc C # hiệu quả của Bill Wagner. Trong Mục 14 - Giảm thiểu Logic Khởi tạo Trùng lặp , anh ấy chỉ ra ví dụ sau về việc sử dụng tính năng tham số tùy chọn mới trong một hàm tạo:

public MyClass(int initialCount = 0, string name = "")

Chú ý rằng anh ấy đã sử dụng ""thay vì string.Empty.
Anh ấy bình luận:

Bạn sẽ lưu ý [trong một ví dụ ở trên] rằng hàm tạo thứ hai đã chỉ định "" cho giá trị mặc định trên tham số tên , thay vì tùy chỉnh hơn string.Empty. Đó là vì string.Emptykhông phải là hằng số thời gian biên dịch. Nó là một thuộc tính tĩnh được định nghĩa trong lớp chuỗi. Bởi vì nó không phải là một hằng số biên dịch, bạn không thể sử dụng nó cho giá trị mặc định cho một tham số.

Nếu chúng ta không thể sử dụng string.Emptystatic trong mọi tình huống, thì điều đó không đánh bại mục đích của nó sao? Tôi nghĩ rằng chúng tôi sẽ sử dụng nó để đảm bảo rằng chúng tôi có một phương tiện độc lập với hệ thống để tham chiếu đến chuỗi trống. Sự hiểu biết của tôi có sai không? Cảm ơn.

CẬP NHẬT
Chỉ là một bình luận tiếp theo. Theo MSDN:

Mỗi tham số tùy chọn có một giá trị mặc định như một phần của định nghĩa của nó. Nếu không có đối số nào được gửi cho tham số đó, giá trị mặc định sẽ được sử dụng. Giá trị mặc định phải là hằng số.

Sau đó, chúng tôi không thể sử dụng System.Environment.NewLinehoặc sử dụng các đối tượng mới được khởi tạo làm giá trị mặc định. Tôi chưa sử dụng VS2010, và điều này thật đáng thất vọng!


2
Tôi không biết về bất kỳ sự khác biệt nào giữa cách các chuỗi trống được biểu diễn trên các nền tảng khác nhau. Nó không giống như dòng mới.
Tom Cabanski

Đúng vậy, tôi đã nghĩ vậy, vậy có phải nó chỉ là mã trông đẹp hơn không?
Mikeyg36

1
CLR chứ không phải 'Hệ thống' là yếu tố quyết định xem "" có phải là một chuỗi rỗng hay không. Vì vậy, tôi nghĩ rằng bạn có thể giả định một cách an toàn "" là một cách độc lập với hệ thống để tham chiếu đến một chuỗi về triển khai CLR tuân thủ.
Chris Taylor

"độc lập với hệ thống"? er, trái ngược với "" dành riêng cho hệ thống? (???)
Qwertie

Theo MSDN: Giá trị của trường này là chuỗi có độ dài bằng 0, "". vì vậy rõ ràng nó không liên quan gì đến tính độc lập của nền tảng, như nhiều người đã chỉ ra. Tuy nhiên, có vẻ như mọi người vẫn không thực sự biết tại sao nó nên được sử dụng!
Mikeyg36

Câu trả lời:


65

Đối với trình biên dịch C # 2.0, dù sao cũng có rất ít điểm String.Empty, và trên thực tế, trong nhiều trường hợp, đó là một sự bi quan, vì trình biên dịch có thể nội tuyến một số tham chiếu đến ""nhưng không thể làm tương tự với String.Empty.

Trong C # 1.1, rất hữu ích để tránh tạo ra nhiều đối tượng độc lập, tất cả đều chứa chuỗi rỗng, nhưng những ngày đó không còn nữa. ""hoạt động tốt.


7
Ngay cả trong .NET 1.1, nó sẽ không tạo ra nhiều đối tượng độc lập. Tôi không thể nhớ chi tiết về sự khác biệt giữa 1.1 và 2.0 về mặt này, nhưng nó không giống như chuỗi ký tự theo nghĩa đen chỉ được giới thiệu trong 2.0.
Jon Skeet

Cảm ơn bạn đã làm rõ. Tôi đã xem xét xung quanh và tôi không tìm thấy bản tóm tắt tốt về những thay đổi trong C # 2.0, mặc dù tôi chắc chắn rằng tôi đã đọc một bản trước đây. Tôi đã tìm thấy câu trả lời của StackOverflow từ năm 2008 với một số liên kết đến thêm thông tin kỹ thuật. stackoverflow.com/questions/151472/…
Andy Mortimer

1
Tôi sẽ gật đầu với điều này, mặc dù tôi không thích nói rằng có rất ít điểm để xâu chuỗi. Tốt vì tôi sử dụng nó khá nhiều. Tôi thấy nó trông sạch sẽ hơn, mặc dù đó là ý kiến ​​cá nhân của tôi. Có rất nhiều nơi string.Empty không thể sử dụng, và tôi không có vấn đề sử dụng "" trong những trường hợp
xximjasonxx

14
Tôi nhận thấy rằng việc nhanh chóng xác định một chuỗi rỗng với String.Empty dễ dàng hơn nhiều so với việc nhìn hai lần vào "" để đảm bảo rằng nó không có dấu nháy đơn hoặc thứ gì đó tương tự ẩn trong đó. +1 cho lời giải thích mặc dù.
NotMe

11
+1 Chris. Ngoài ra trong VS, bạn thực sự không thể thực hiện tìm kiếm trên tập quán của "" (ngoài việc thực hiện Tìm kiếm thông thường, thao tác này cũng sẽ trả về mọi kết quả khớp văn bản, bao gồm cả nhận xét và đánh dấu). Bạn có thể thực hiện tìm kiếm trên các mã sử dụng cụ thể với string.Empty.
MutantNinjaCodeMonkey

53

Không có gì ngăn bạn xác định hằng số của riêng bạn cho chuỗi trống nếu bạn thực sự muốn sử dụng nó như một giá trị tham số tùy chọn:

const string String_Empty = "";

public static void PrintString(string s = String_Empty)
{
    Console.WriteLine(s);
}

[Ngoài ra, một lý do để thích String.Emptyhơn ""nói chung, chưa được đề cập đến trong các câu trả lời khác, là có nhiều ký tự Unicode khác nhau (bộ nối có độ rộng bằng không, v.v.) có thể nhìn thấy bằng mắt thường. Vì vậy, một cái gì đó trông giống như ""không nhất thiết phải là chuỗi trống, ngược lại String.Emptybạn biết chính xác những gì bạn đang sử dụng. Tôi nhận ra đây không phải là nguồn phổ biến của lỗi, nhưng nó có thể xảy ra.]


2
Ngoài ra còn có các ký tự định danh vô hình, vì vậy không nhất thiết phải có một cái gì đó giống như String_Empty. Tiêu chuẩn Unicode có một chương bị bỏ qua phần lớn về các cân nhắc bảo mật.
Jim Balter

25

Từ câu hỏi ban đầu:

Tôi nghĩ rằng chúng tôi sẽ sử dụng nó để đảm bảo rằng chúng tôi có một phương tiện độc lập với hệ thống để tham chiếu đến chuỗi trống.

Chuỗi rỗng có thể thay đổi theo cách nào giữa các hệ thống? Nó luôn luôn là một chuỗi không có ký tự! Tôi thực sự sợ hãi nếu tôi đã từng tìm thấy một triển khai trong đó string.Empty == ""trả về false :) Điều này không giống như một cái gì đó giống như Environment.NewLine.

Từ bài đăng tiền thưởng của Counter Terrorist:

Tôi muốn String.Empty có thể được sử dụng làm tham số mặc định trong bản phát hành C # tiếp theo. : D

Điều đó chắc chắn sẽ không xảy ra.

Mặc dù cá nhân tôi cũng thích một cơ chế mặc định rất khác, nhưng cách các tham số tùy chọn hoạt động đã có trong .NET kể từ khi bắt đầu - và điều đó luôn có nghĩa là nhúng một hằng số vào siêu dữ liệu, để mã gọi có thể sao chép hằng số đó vào lệnh gọi nếu không có đối số tương ứng được cung cấp.

Với string.Emptythực sự vô nghĩa - sử dụng ""sẽ làm những gì bạn muốn; nó đau đớn khi sử dụng chuỗi theo nghĩa đen? (Tôi sử dụng nghĩa đen ở khắp mọi nơi - tôi không bao giờ sử dụng string.Empty- nhưng đó là một lập luận khác.)

Đó là điều làm tôi ngạc nhiên về câu hỏi này - lời phàn nàn xoay quanh điều gì đó không thực sự gây ra vấn đề thực sự. Nó quan trọng hơn trong các trường hợp bạn muốn tính toán mặc định tại thời điểm thực thi vì nó thực sự có thể khác nhau. Ví dụ: tôi có thể tưởng tượng các trường hợp bạn muốn có thể gọi một phương thức với một DateTimetham số và đặt nó mặc định là "thời gian hiện tại". Hiện tại, cách giải quyết mơ hồ duy nhất mà tôi biết cho đó là:

public void RecordTime(string message, DateTime? dateTime = null)
{
    var realDateTime = dateTime ?? DateTime.UtcNow;
}

... nhưng điều đó không phải lúc nào cũng thích hợp.

Tóm lại là:

  • Tôi rất nghi ngờ rằng đây sẽ là một phần của C #
  • string.Emptydù sao nó cũng vô nghĩa
  • Đối với các giá trị khác thực sự không phải lúc nào cũng có cùng giá trị, nó thực sự có thể là một nỗi đau

Đây thực sự là một cách tốt để khắc phục sự cố. Điều tương tự cũng có thể được sử dụng để thực hiện / đặt các biến phụ thuộc thiết bị khác như Environment.Newline.. Điều duy nhất còn thiếu trong ví dụ của bạn sẽ là kiểm tra biến cho giá trị null và ném lại một ngoại lệ cho nhà phát triển nói với anh ta rằng mặc dù nó có giá trị vô hiệu, nhưng nó không được chấp nhận. if(dateTime == null){ throw new ArgumentException("The dateTime parameter must be set. Nullable type used for device independent variable set.");}hoặc điều tương tự. Nhưng tôi thực sự thích điều này! Bất kỳ lưu ý nào khác để làm theo cách của bạn?
MaxOvrdrv

@MaxOvrdrv: Bạn không muốn nó là null là một lỗi - điểm chung là khi nó null, bạn sẽ tính giá trị mặc định. Lưu ý là nó không cho phép null được chuyển qua như một giá trị hợp lệ.
Jon Skeet

Bạn hoàn toàn đúng về điều đó. Lỗi của tôi. - Và vâng, đó sẽ là cảnh báo thực sự duy nhất phải không ... điều đó không quá tệ. Một lần nữa: tôi thực sự thích giải pháp này! :) Cảm ơn vì đã đăng nó! :)
MaxOvrdrv

7

Tôi không bao giờ sử dụng string.Empty, tôi không thể thấy điểm của nó. Có thể nó giúp những người mới làm quen với lập trình trở nên dễ dàng hơn, nhưng tôi nghi ngờ nó có ích ngay cả với điều đó.


2
Có lẽ nó tránh gây nhầm lẫn """ ", nhưng tôi không thể nói rằng đó " "là tất cả những điều phổ biến.
Greg

8
Tôi khuyên rằng bất cứ ai không thể phân biệt được sự khác biệt giữa những nhu cầu đó là kính tốt hơn hoặc giảm độ phân giải màn hình của họ. Tôi có thị lực kém và tôi không thể nhớ đã bao giờ mắc lỗi đó (và tôi phải làm việc với rất nhiều mã chứa cả hai điều đó).
Hans Olsson

2
string.Empty rất hữu ích để tìm ra ý định chính xác của lập trình viên. "" không cho biết bất cứ điều gì về ý định, điều gì sẽ xảy ra nếu ý định của lập trình viên là khởi tạo biến như thế này "lol" nhưng lại quên ... trong trường hợp này có vô số khả năng và chuỗi, Empty có ích và hoạt động tốt hơn
íchBee

4

Tôi nghĩ ý tưởng đằng sau string.Empty là nó tăng cường khả năng đọc. Nó không giống như newline ở chỗ có bất kỳ sự khác biệt nào giữa cách nó được thể hiện trên các nền tảng khác nhau. Nó không thể được sử dụng trong một tham số mặc định. Tuy nhiên, nó sẽ không gây ra bất kỳ vấn đề nào nếu bạn chuyển giữa Windows và một cái gì đó như Mono trên Linux.


5
Tôi nghĩ rằng bạn có thể đúng rằng điểm mà một số người coi là String.Emptydễ đọc hơn. . . Tuy nhiên, cá nhân tôi nghĩ điều đó hơi hấp dẫn. ""có lẽ là chuỗi phổ biến nhất ở đó và mọi người đã nhìn thấy nó hàng tỷ lần, vậy làm thế nào để nó không thể đọc được? String.Emptylà hữu ích như thể có một Int32.Zero.
Tim Goodman

3

Là một FYI, có vẻ như cùng một ràng buộc được áp đặt cho các giá trị được truyền cho các hàm tạo thuộc tính - chúng phải không đổi. Vì string.empty được định nghĩa là:

public static readonly string Empty

chứ không phải là một hằng số thực tế, nó không thể được sử dụng.


1

Tôi sử dụng string.Emptyhoàn toàn để dễ đọc.

Nếu sau này ai đó cần đọc / thay đổi mã của tôi thì họ biết rằng tôi muốn kiểm tra hoặc đặt một thứ gì đó thành một chuỗi trống. Chỉ sử dụng"" đôi khi có thể gây ra lỗi và nhầm lẫn vì tôi có thể đã quên đặt chuỗi mà tôi muốn vào đó.

Ví dụ:

if(someString == string.Empty)
{

}

vs

if(someString == "")
{

}

ifTuyên bố đầu tiên có vẻ cân nhắc và dễ đọc hơn đối với tôi. Bởi vì đây chỉ là một tùy chọn, tôi thực sự không thấy việc phải sử dụng xe lửa để ""thay thế string.Empty.


-2

Có lẽ giải pháp tốt nhất cho vấn đề này là quá tải của phương thức này, theo cách này:

public static void PrintString() 
{ 
    PrintString(string.Empty);
}

3
Đó là câu trả lời cho câu hỏi trên như thế nào?
Pranav Singh

1
Nó trợ giúp như thế nào với các giá trị mặc định cho các tham số tùy chọn?
ngôn ngữ mặc định
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.