2010-03-30 24 views
10

Bạn có nghĩ rằng C# sẽ hỗ trợ một cái gì đó như ?? = toán tử?Bạn nghĩ gì về toán tử =? Trong C#?

Thay vì điều này:

if (list == null) 
    list = new List<int>(); 

Nó có thể là có thể viết:

list ??= new List<int>(); 

Bây giờ, tôi có thể sử dụng (nhưng có vẻ như với tôi không tốt có thể đọc được):

list = list ?? new List<int>(); 
+0

Điều đó sẽ thật tuyệt! Không chắc chắn nếu nó hỗ trợ nó ... nhưng có, tôi thích nó! – Zoidberg

+0

Đề xuất ý tưởng này làm cho các bộ phận Ruby của tôi trở nên ấm áp. (Xem Ruby '|| =' nhà điều hành.) –

Trả lời

4

Tôi luôn muốn có thứ như thế này. Tôi sẽ sử dụng nó thường xuyên hơn chính bản thân số ??.

Những gì tôi thực sự muốn, mặc dù, là một dạng toán tử cho phép bạn coi trọng đối tượng chỉ khi không rỗng. Để thay thế này:

int count = (list != null)? list.Count : 0 

với một cái gì đó như thế này:

int count = list??.Count : 0 

Đó sẽ là đặc biệt hữu ích cho tôi với chuỗi dài các tài liệu tham khảo (thiết kế xấu, tôi biết), nhưng ví dụ

int count = foo??.bar??.baz??.list??.Count : 0 

Hiện tại, bạn không thể thực hiện điều này với ?? vì bạn chỉ có thể nói "chỉ định cho foo hoặc thay thế nếu null" nhưng không "chỉ định cho thuộc tính của foo, hoặc thay thế nếu null. "

+0

Trong khi tôi đồng ý, tôi nghĩ rằng điều này đi ngược lại cách C# hoạt động nói chung. Nó nhắc tôi nhiều hơn về các ngôn ngữ thông điệp như Obj-C, trong đó [danh sách đếm]; sẽ trả về null thay vì bắn một lỗi ngoại lệ null. Trong C#, nó làm cho cú pháp trở nên khó hiểu hơn nhiều, đặc biệt là vì trong trường hợp này bạn hầu như luôn muốn sử dụng nó. – Jess

+0

tất nhiên tôi đồng ý, giống như bất cứ điều gì, nó có thể nguy hiểm trong tay kẻ xấu. Tôi không có cách nào cho rằng việc thay thế này để xử lý lỗi bằng cách bỏ qua tất cả các tham chiếu null. Nhưng có một số trường hợp mà null là hoàn toàn có thể chấp nhận được, và bạn có một giá trị thay thế hợp lệ để sử dụng trong trường hợp đó. – Tesserex

+5

Đây là tính năng được yêu cầu thường xuyên. Chúng tôi đang xem xét nó. –

3

Tôi thích nó - đó là một cách tốt đẹp, ngắn gọn để thể hiện một biểu thức lười biếng. Cho dù nó có được thêm vào ngôn ngữ hay không là một điều hoàn toàn khác - như Eric Lippert loves to point out, các tính năng mới yêu cầu một lượng đáng kể công việc để thực hiện và vì vậy chúng phải đóng góp tích cực đáng kể cho ngôn ngữ để được đưa vào.

+3

Thật vậy, tôi không thấy một lợi ích to lớn ở đây. Tôi hơi ngạc nhiên khi một nhà điều hành "không hợp tác với nhiệm vụ" không được thêm vào khi ?? đã được thêm vào, nhưng nó thực sự không thêm nhiều sức mạnh. –

16

Cá nhân tôi nghĩ rằng chỉ có việc mở rộng thứ hai có ý nghĩa (về giữ dọc theo dòng giống như += vv):

list = list ?? new List<int>(); 

nhưng phải trung thực tôi tìm thấy nó một chút không cần thiết. Mọi người thường "nhận" i += 5;, nhưng có xu hướng có vấn đề với việc hợp nhất null (??). Thêm một toán tử gán kết hợp null và ... tốt, tôi không thấy nó kết thúc tốt.

Cá nhân tôi ủng hộ mã gốc:

if(list == null) { list = new List<int>(); } 
.... 

Ngoài ra - xem xét: trong tất cả các khác +=, -= vv - phía bên tay phải luôn được đánh giá. Trong trường hợp này nó sẽ không được (trong một số trường hợp). Điều đó làm tăng thêm sự nhầm lẫn. Ý tôi là:

i += SomethingCriticalThatMustBeCalled(); // fine - always runs 
j ??= SomethingElseCriticalThatMustBeCalled(); // is this run? if j != null? 
+1

Tôi đồng ý. Đó là sự lựa chọn giữa tốc độ viết và dễ đọc. Khả năng đọc sẽ thắng mọi lúc. –

+3

Tôi đồng ý rằng khả năng đọc có giá trị cao, nhưng tôi thấy toán tử ?? = khá dễ nắm bắt (sau đó một lần nữa, tôi thích haskell vì vậy có thể tôi đã quen với các toán tử tùy ý). Nhưng tôi không nghĩ rằng ví dụ thứ hai của Marc là một ví dụ rất hay. Bạn không nên chạy mã quan trọng như là một tác dụng phụ của một + = anyway, do đó, nó rất contrived. – CodexArcanum

4

Một lừa tôi thấy đâu đó ở đây trên stackoverflow là để làm một cái gì đó như thế này ...

private List<string> myList; 
public List<string> MyProp 
{ 
    get { return myList ?? (myList= new List<string>()); } 
} 

... bạn có thể có thể sử dụng eval lười biếng tương tự trong mã của bạn.