2010-04-23 78 views
76

Tôi đang đọc Hiệu quả C# bởi Bill Wagner. Trong mục 14 - Giảm thiểu Duplicate Khởi logic, ông cho thấy ví dụ sau đây của việc sử dụng các thông số tùy chọn tính năng mới trong một constructor:Không thể sử dụng String.Empty làm giá trị mặc định cho thông số tùy chọn

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

ý rằng ông sử dụng "" thay vì string.Empty.
Ông bình luận:

Bạn sẽ lưu ý [trong ví dụ trên] rằng các nhà xây dựng thứ hai quy định "" cho giá trị mặc định vào tên tham số , chứ không phải là phong tục hơn string.Empty. Đó là vì string.Empty không phải là hằng số 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 tôi không thể sử dụng số string.Empty tĩnh trong mọi trường hợp, thì điều đó không đánh bại mục đích của nó? Tôi nghĩ rằng chúng tôi sẽ sử dụng nó để chắc chắn rằng chúng tôi có một phương tiện độc lập hệ thống đề cập đến chuỗi rỗng. Sự hiểu biết của tôi có sai không? Cảm ơn.

CẬP NHẬT
Chỉ cần nhận xét tiếp theo. Theo MSDN:

Mỗi thông số tùy chọn có giá trị mặc định là một phần của định nghĩa. 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.NewLine một trong hai hoặc sử dụng các đối tượng mới được 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 bất kỳ sự khác biệt nào về cách chuỗi rỗng được thể hiện trên các nền tảng khác nhau. Nó không giống như dòng mới. –

+0

Phải, tôi đã nghĩ rằng, vậy thì chỉ có nó trông đẹp hơn trong mã? – Mikeyg36

+1

CLR và không phải là 'Hệ thống' là yếu tố quyết định xem liệu "" 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 trên thực thi CLR tuân thủ. –

Trả lời

52

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

Trong C# 1.1, thật hữu ích khi tránh tạo nhiều đối tượng độc lập, tất cả chứa chuỗi rỗng, nhưng những ngày đó đã biến mất. "" hoạt động tốt.

+7

Ngay cả trong .NET 1.1 nó sẽ không tạo ra "rất nhiều" của các đối tượng độc lập. Tôi không thể nhớ các chi tiết về sự khác biệt giữa 1,1 và 2,0 về khía cạnh này, nhưng nó không giống như việc thực hiện chuỗi ký tự bằng chữ chỉ được giới thiệu trong 2.0. –

+0

Cảm ơn bạn đã làm rõ. Tôi đã có một cái nhìn xung quanh và tôi đã không tìm thấy một 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 trước đó. Tôi đã tìm thấy một câu trả lời StackOverflow từ năm 2008 với một số liên kết đến thông tin kỹ thuật hơn. http://stackoverflow.com/questions/151472/what-is-the-difference-between-string-empty-and –

+1

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

7

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

+2

Có thể nó ngăn cản nhầm lẫn '" "' và '" "', nhưng tôi không thể nói rằng '" "' là tất cả những gì phổ biến. – Greg

+8

Tôi muốn đề nghị rằng bất kỳ ai không thể nói 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 xấu và tôi không thể nhớ lại bao giờ làm sai lầm đó (và tôi phải làm việc với rất nhiều mã có chứa cả hai điều đó). –

+1

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 nói gì về ý định, 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 quên ... trong trường hợp này có vô số khả năng và chuỗi, Empty có ích và làm tốt hơn – usefulBee

4

Tôi nghĩ ý tưởng đằng sau chuỗi.Empty là nó giúp tăng cường khả năng đọc. Nó không giống như dòng mới, nơi có bất kỳ sự khác biệt giữa cách nó được thể hiện trên các nền tảng khác nhau. Đó là ashame 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ếu bạn cổng giữa Windows và một cái gì đó như Mono trên Linux.

+5

I nghĩ rằng bạn có thể đúng rằng điểm là một số người xem xét 'String.Empty' dễ đọc hơn. . . cá nhân, mặc dù tôi nghĩ rằng đó là một chút hấp dẫn. '" "' có lẽ là chuỗi phổ biến nhất ở đó và mọi người đã thấy nó một tỷ lần, vậy làm sao nó không thể đọc được? 'String.Empty' là hữu ích như thể có một' Int32.Zero'. –

50

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

const string String_Empty = ""; 

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

[Là một sang một bên, một lý do để thích String.Empty qua "" nói chung, điều đó đã không được đề cập trong các câu trả lời khác, là có nhiều ký tự Unicode khác nhau (không có chiều rộng joiners, vv) có hiệu quả vô hình với 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 rỗng, trong khi với String.Empty bạ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à một lỗi phổ biến, nhưng có thể.]

+12

+1. Bạn làm cho "String.Empty" có vẻ như nó có một mục đích! – TarkaDaal

+2

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

3

Như 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 nhà xây dựng 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à hằng số thực tế, không thể sử dụng.

20

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

tôi nghĩ rằng chúng tôi sẽ sử dụng nó để chắc chắn rằng chúng tôi có một phương tiện hệ thống độc lập với ám chỉ đến chuỗi rỗng.

Chuỗi cách nào có thể thay đổi từ hệ thống sang hệ thống? Nó luôn luôn là một chuỗi không có ký tự! Tôi muốn được 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 :) Đây là không phải giống như một cái gì đó như Environment.NewLine.

Từ bài bounty Counter Terrorist của:

Tôi muốn String.Empty thể được sử dụng như một tham số mặc định trong thư mục C# phiên bản 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 cơ chế mặc định rất khác nhau, cách thức hoạt động của tham số tùy chọn đã ở trong .NET từ đầu - và nó 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 liên tục vào trang cuộc gọi nếu không có đối số tương ứng nào được cung cấp.

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

Đó là điều khiến tôi ngạc nhiên về câu hỏi này. Nó cho quan trọng hơn trong trường hợp bạn muốn mặc định được tính toán tại thời gian thực hiện bởi 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 mà bạn muốn có thể gọi một phương thức với tham số DateTime và đặt mặc định là "thời gian hiện tại".Hiện tại, giải pháp thay thế chỉ có một cách mơ hồ mà tôi biết 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 phù hợp.

Tóm lại:

  • Tôi rất nghi ngờ rằng điều này sẽ không bao giờ là một phần của C#
  • Đối string.Empty đó là vô nghĩa nào
  • Đối với các giá trị khác mà thực sự không luôn có cùng một giá trị, nó thực sự có thể là một cơn đau
+0

Đây thực sự là một cách tốt để khắc phục sự cố. Điều tương tự có thể được sử dụng để thực hiện/thiết lập 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à một kiểm tra trên biến cho null, và ném một ngoại lệ trở lại cho nhà phát triển nói anh ta rằng trong khi nó vô hiệu, nó không được chấp nhận. '' if (dateTime == null) {throw new ArgumentException ("Tham số dateTime phải được thiết lập. Kiểu dữ dội được sử dụng cho bộ biến độc lập thiết bị.");} '' hoặc một cái gì đó tương tự. Nhưng tôi thực sự thích điều này! Bất kỳ sự cẩn thận nào khác để thực hiện theo cách của bạn? – MaxOvrdrv

+0

@MaxOvrdrv: Bạn không muốn nó bị vô hiệu là lỗi - toàn bộ vấn đề là khi nó rỗng, bạn tính toán một mặc định. Thông báo trước là nó không cho phép null được chuyển qua như một giá trị hợp lệ trong chính nó. –

+0

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 sẽ 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 bạn đã đăng nó! :) – MaxOvrdrv

2

Nếu bạn thực sự không thích st literals nhẫn, bạn có thể sử dụng:

public static string MyFunction(string myParam= default(string)) 
+2

default (string) sẽ trả về null, không phải string.Empty. – lgaud

+0

http://msdn.microsoft.com/en-us/library/xwth0h0d.aspx Ah đúng. Tôi quên chuỗi thực sự là một tham chiếu và không phải là một giá trị. –

-1

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

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

Cách trả lời câu hỏi trên? –

+1

Làm cách nào để trợ giúp với các giá trị mặc định cho các tham số tùy chọn? –

0

tôi sử dụng string.Empty hoàn toàn để có thể đọc.

Nếu người khác cần phải đọc/thay đổi mã của tôi sau đó họ biết rằng tôi muốn kiểm tra hoặc đặt thứ gì đó thành chuỗi trống. Sử dụng chỉ "" đôi khi có thể gây ra lỗi và nhầm lẫn vì tôi có thể vừa quên đặt chuỗi mà tôi muốn trong đó.

Ví dụ:

if(someString == string.Empty) 
{ 

} 

vs

if(someString == "") 
{ 

} 

Các if lệnh đầu tiên chỉ có vẻ nhiều hơn nữa cố ý và có thể đọc được với tôi. Bởi vì đây chỉ là một ưu tiên mặc dù, tôi thực sự không nhìn thấy xe lửa-smash trong việc phải sử dụng "" thay vì string.Empty.

Các vấn đề liên quan