2014-10-24 12 views
13

Với đoạn mã sau, Resharper sẽ đúng cảnh báo tôi về một thể NullReferenceException trên foo.Bar bởi vì có thể các yếu tố null trong đếm được:Làm thế nào để tôi cho Resharper biết rằng phương thức IEnumerable của tôi có thể loại bỏ null?

IEnumerable<Foo> foos = GetFoos(); 
var bars = foos.Select(foo => foo.Bar); 

Một cách để đáp ứng các phân tích tĩnh là để loại trừ một cách rõ ràng null:

IEnumerable<Foo> foos = GetFoos().Where(foo => foo != null); 

tôi thấy mình gõ .Where(x => x != null) rất nhiều, vì vậy tôi đã kết thúc trong một phương pháp khuyến nông, và bây giờ tôi có thể làm như sau:

IEnumerable<Foo> foos = GetFoos().NotNull(); 

Vấn đề là Resharper không biết rằng NotNull() loại bỏ các giá trị rỗng. Có cách nào tôi có thể dạy Resharper về thực tế này không? Nói chung, có cách nào để nói với Resharper rằng phương thức trả về IEnumerable sẽ không bao giờ có null trong nó (để tôi có thể chỉ chú thích trực tiếp GetFoos())?

Tôi biết tôi có thể sử dụng the NotNullAttribute để thông báo cho Người chia sẻ lại rằng bản thân số đó không phải là số không, nhưng tôi không thể tìm thấy nội dung nói về nội dung của số đếm.

Edit: Phương pháp mở rộng trông giống hệt như bạn mong muốn:

[NotNull] 
public static IEnumerable<T> NotNull<T>(this IEnumerable<T> enumerable) 
{ 
    return enumerable.Where(x => x != null); 
} 
+0

Tôi không sử dụng tính năng chia sẻ lại. Nhưng nếu nó biết rằng 'foo! = Null' ngăn chặn một' NullReferenceException', tại sao nó không biết rằng 'NotNull' cũng bỏ qua null-foos? Bạn cũng có thể hiển thị 'NotNull'? –

+1

@Tim họ có một số quy tắc được xây dựng trong các plugin, vì vậy nó biết những gì '.Where (...)' không ví dụ, và các công cụ phân tích có thể hành động cho phù hợp. Nhưng nó không đào sâu bên trong phương thức người dùng, bởi vì việc giải quyết điều này trong trường hợp chung sẽ tương đương với việc giải quyết vấn đề [halting problem] (http://en.wikipedia.org/wiki/Halting_problem). Đáng buồn thay, tôi không nghĩ rằng có một cách để chú thích quy tắc cụ thể này ... '[ContractAnnotation (" ?? ")]' có thể là một giải pháp nhưng không có cú pháp cho enumerables hoặc. –

+0

@TimSchmelter Tôi không biết, nhưng tôi nghi ngờ đó là bởi vì các phân tích không làm kiểm tra phương pháp sâu để xác định nơi nullability được kiểm tra lần cuối. Tôi biết rằng Resharper tạo ra những sai lầm thú vị khác trong lĩnh vực này - ví dụ, nếu tôi lọc ra các giá trị rỗng bằng '.Where', và sau đó lập tức chuỗi' .OrderBy', Resharper dường như mất kiến ​​thức về các giá trị rỗng đã được lọc ra. – ean5533

Trả lời

3

Bạn có thể sử dụng ItemNotNullAttribute thông báo cho ReSharper rằng không có mục nào trong bộ sưu tập có thể là null.

+0

Tuyệt vời! Có vẻ như họ đã thêm vào năm 2016 - rất vui. – ean5533

1

Một cách như bạn đã nêu là sử dụng [notnull] thuộc tính này hướng dẫn các cơ Resharper ngừng kiểm tra lỗi tham chiếu null cho biến cụ thể đó.

Hoặc khác nếu bạn không muốn sử dụng thuộc tính mà bạn có thể tùy chọn sử dụng các ý kiến ​​

// ReSharper disable PossibleNullReferenceException 
     var bars = foos.Select(foo => foo.Bar); 
// ReSharper restore PossibleNullReferenceException 

Để thực hiện một điểm cho câu hỏi này, Resharper không thể đi qua thông qua thời gian chạy các giá trị tính toán tuyên bố, do đó nó có thể làm cho một phán xét rằng nó không thể là rỗng.

+0

Thuộc tính 'NotNull' sẽ chỉ xác minh rằng * enumerable * không phải là null, nó sẽ không xác minh rằng * kết quả * của enumerable không phải là null. Ngoài ra, như đã nêu trong các ý kiến ​​ở trên, tôi không muốn liên tục vô hiệu hóa kiểm tra tham chiếu null mỗi khi tôi sử dụng một số đếm. – ean5533

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