2010-05-14 28 views
21

Theo như tôi biết có không phải là một đáng kể cách thanh lịch hơn để viết như sau ....Shorthand cho lồng nhau kiểm tra null C#

string src; 
if((ParentContent!= null) 
    &&(ParentContent.Image("thumbnail") != null) 
    &&(ParentContent.Image("thumbnail").Property("src") != null)) 
    src = ParentContent.Image("thumbnail").Property("src").Value 

Bạn có nghĩ rằng cần có một tính năng ngôn ngữ C# để làm ngắn hơn?
Và nếu có, nó sẽ trông như thế nào? Ví dụ:
, chẳng hạn như mở rộng ?? nhà điều hành

string src = ParentContent??.Image("thumbnail")??.Property("src")??.Value; 

Xin lỗi cho ví dụ khá giả mạo và giải pháp quá đơn giản của tôi.

Chỉnh sửa ... Nhiều năm sau
này bây giờ là một tính năng ngôn ngữ kế hoạch gọi là "Null hành tuyên truyền" ?. https://roslyn.codeplex.com/discussions/540883 (Cảm ơn @ Brian)

+0

Chắc chắn hấp dẫn với chiếc răng ngọt ngào của tôi! –

+1

Xem https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Documentation và https://roslyn.codeplex.com/discussions/540883. Tính năng này sẽ sớm khả dụng. – Brian

+0

Nó đến trong C# 6! –

Trả lời

18

Không có built-in cú pháp để thực hiện điều này, nhưng bạn có thể xác định một phương pháp khuyến nông để làm điều này:

R NotNull<T, R>(this T src, Func<T, R> f) 
    where T : class where R : class { 
    return src != null ? f(src) : null; 
} 

Bây giờ, bạn có thể viết lại ví dụ của bạn như sau:

src = ParentContent.NotNull(p => p.Image("thumbnail")). 
     NotNull(i => i.Property("src")).NotNull(src => src.Value); 

Nó không phải là tốt đẹp như nó có thể được với một hỗ trợ cú pháp, nhưng tôi muốn nói nó dễ đọc hơn nhiều.

Lưu ý rằng điều này thêm phương thức NotNull cho tất cả các loại .NET, điều này có thể hơi bất tiện. Bạn có thể giải quyết điều đó bằng cách xác định loại trình bao bọc đơn giản WrapNull<T> where T : class chỉ chứa một giá trị loại T và một phương pháp để chuyển bất kỳ loại tham chiếu nào thành WrapNull và cung cấp NotNull trong loại WrapNull. Sau đó, các mã sẽ trông như thế này:

src = WrapNull.Wrap(ParentContent).NotNull(p => p.Image("thumbnail")). 
     NotNull(i => i.Property("src")).NotNull(src => src.Value); 

(Vì vậy, bạn sẽ không gây ô nhiễm IntelliSense của mỗi loại với các phương pháp khuyến nông mới)

Với nỗ lực hơn một chút, bạn cũng có thể xác định một truy vấn LINQ các nhà khai thác để làm điều này. Đây là một chút overkill, nhưng nó có thể viết này (tôi sẽ không bao gồm các định nghĩa ở đây như họ là một chút nữa, nhưng nó có thể trong trường hợp ai đó quan tâm :-)).

src = from p in WrapNull.Wrap(ParentContent) 
     from i in p.Image("thumbnail"). 
     from src in i.Property("src") 
     select src.Value; 
+2

Tôi phải nói rằng, tôi phải đọc khoảng 5 lần để đọc nó đúng cách. Đôi khi đọc mã chức năng khiến tôi rất tiếc khi bắt đầu với ngôn ngữ kiểu thủ tục thay vì nói LISP. Những ngày khác, tôi cảm ơn sự tỉnh táo của tôi tôi đã không! : D – Serapth

+0

@Serapth: Tôi nghĩ rằng một điều là đọc việc thực hiện (và hiểu cách nó hoạt động) và một điều khác là đọc mã người dùng. Giải thích cách sử dụng phương thức mở rộng 'NotNull' của tôi không phải là khó khăn (có thể tôi không làm tốt ở đây :-)). –

+0

Ồ không, tôi đồng ý hoàn toàn. Trên thực tế sử dụng các phương pháp mở rộng là không có trí tuệ và hoàn toàn dễ đọc, nhiều hơn như vậy ngay cả khi các bài viết ban đầu được đề nghị giải pháp. Đó là phương pháp mở rộng chính nó là kinh khủng khó khăn cho tôi để đọc. Điều đó nói rằng, chức năng lập trình không phải là tự nhiên trực quan với tôi và sự thật nói, tôi đã luôn luôn tìm thấy mã templated thêm một lớp của sự nhầm lẫn với kịch bản là tốt. Tôi nghĩ đó chỉ là cách mà bộ não của tôi có dây. Tôi hiểu cú pháp, những gì đang xảy ra và cách nó hoạt động, tôi chỉ cần đọc nó một lần nữa và một lần nữa để làm theo cách nó hoạt động. – Serapth

16

Nó được gợi ý và dường như từ chối bởi nhóm:

A bit more C# syntactic sugar for nulls

Cú pháp được đề xuất sẽ xem xét ike a.?b.?c() - rất hữu ích và rõ ràng.

Tôi thực sự rất muốn xem nó, nhưng không có vẻ như nó sẽ xảy ra. Có lẽ nếu đủ người bỏ phiếu cho nó!

+3

+1 tôi sẽ bỏ phiếu bầu của tôi –

15

Chúng tôi coi nó là C# 4 nhưng không có ngân sách. Đó là một tính năng tuyệt vời mà rất nhiều người yêu cầu, vì vậy có lẽ chúng tôi sẽ đưa nó vào một phiên bản ngôn ngữ giả định trong tương lai. Không hứa hẹn.

+9

Một ngày nào đó, Eric sẽ có một ngày dài và sẽ quá mệt mỏi. Và vào ngày đó, anh ta sẽ nói, "chúng tôi đang xem xét điều này cho phiên bản tiếp theo của C#." – Brian

+1

Hãy cân nhắc! :-) – Myster

+0

Hãy tiếp tục xem xét .... 3 năm sau :) – Jack

0

Nó vẫn để lại một chút để được mong muốn nhưng tôi muốn viết nó như thế này:

var src = ParentContent == null ? null 
    : ParentContent.Image("thumbnail") == null ? null 
    : ParentContent.Image("thumbnail").Property("src") == null ? null 
    : ParentContent.Image("thumbnail").Property("src").Value; 
1

Đúng tôi, nếu tôi sai, nhưng điều này có thể được giải quyết bằng C# 6.0 của null-conditional operator:

string src = ParentContent?.Image("thumbnail")?.Property("src")?.Value; 

Nếu src là đã có trong sử dụng trước khi chuyển nhượng giá trị này, bạn có thể sử dụng nó như sau:

string src = ....; 

// ... 

src = ParentContent?.Image("thumbnail")?.Property("src")?.Value ?? src; 

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