2010-12-08 39 views
7

Dưới đây là một đoạn mã:ReSharper: làm thế nào để loại bỏ "có thể xảy ra 'System.NullReferenceException'" cảnh báo

 IUser user = managerUser.GetUserById(UserId); 
     if (user==null) 
      throw new Exception(...); 

     Quote quote = new Quote(user.FullName, user.Email); 

Mọi việc đã ổn ở đây. Nhưng nếu tôi thay thế "nếu" phù hợp với một sau:

 ComponentException<MyUserManagerException>.FailIfTrue(user == null, "Can't find user with Id=" + UserId); 

nơi thực hiện chức năng là như sau:

public abstract class ComponentException<T> : ComponentException 
     where T : ComponentException, new() 
{ 
    public static void FailIfTrue(bool expression, string message) 
    { 
     if (expression) 
     { 
      T t = new T(); 
      t.SetErrorMessage(message); 
      throw t; 
     } 
    } 
    ... 
} 

Sau đó resharper tạo cho tôi một cảnh báo: Có thể 'System.NullReferenceException' chỉ vào cách sử dụng 1 đối tượng 'người dùng'.

Q1. Tại sao nó tạo ra ngoại lệ như vậy? Theo như tôi thấy nếu 'user == null' thì ngoại lệ sẽ được tạo và việc thực hiện sẽ không bao giờ đạt đến điểm sử dụng.

Q2. Làm thế nào để loại bỏ cảnh báo đó? Xin lưu ý: 1. Tôi không muốn ngăn chặn cảnh báo này với các bình luận (Tôi sẽ có rất nhiều phần tương tự và không muốn chuyển đổi mã nguồn của tôi trong 'garbase nhận xét); 2. Tôi không muốn thay đổi cài đặt chia sẻ lại để thay đổi vấn đề này từ cảnh báo thành 'gợi ý' của 'gợi ý'.

Cảm ơn.

Bất kỳ ý tưởng nào đều được hoan nghênh!

P.S. Tôi đang sử dụng resharper 5.1, MVSV 2008, C#

Trả lời

6

Q1: Vì Resharper không thực hiện phân tích đường dẫn. Nó chỉ thấy một tài liệu tham khảo có thể là null và gắn cờ đó.

Q2: Bạn không thể thực hiện bất kỳ điều gì bạn đã cung cấp.

0

Điều này là do công cụ Resharper gây ra. Những "NullReferenceException" có thể xảy ra bởi vì ai đó (có thể tại Resharper) đã khai báo/cấu hình ở đâu đó một chú thích trên phương thức.

Dưới đây là cách hoạt động: ReSharper NullReferenceException Analysis and Its Contracts

Thật không may, đôi khi, những chú thích hữu ích chỉ là sai.

Khi bạn phát hiện lỗi, bạn nên báo cáo lỗi đó với JetBrains và họ sẽ cập nhật chú thích trên bản phát hành tiếp theo. Họ đã quen với điều này.

Trong khi đó, bạn có thể tự mình khắc phục. Đọc bài viết để biết thêm :)

10

Trình chia sẻ lại chỉ xem xét phương pháp hiện tại để phân tích và không phân tích đệ quy các phương pháp khác mà bạn gọi.

Tuy nhiên, bạn có thể trực tiếp Resharper một chút và cung cấp thông tin meta về một số phương pháp nhất định. Nó biết ví dụ về "Assert.IsNotNull (a)", và sẽ đưa thông tin đó vào tài khoản để phân tích. Có thể tạo một tệp chú thích bên ngoài để Resharper và cung cấp thêm thông tin về một thư viện nhất định để làm cho phân tích của nó tốt hơn. Có lẽ điều này có thể cung cấp một cách để giải quyết vấn đề của bạn.

Thông tin khác có thể được tìm thấy here.

Ví dụ hiển thị cách nó được sử dụng cho thư viện Microsoft.Hợp đồng có thể được tìm thấy here.

3

Bạn biết (hoặc mong đợi) rằng mã này sẽ ném một ngoại lệ nếu có một tham chiếu null:

ComponentException<MyUserManagerException>.FailIfTrue([...]); 

Tuy nhiên, vì không có hợp đồng quy định cụ thể này, ReSharper có giả định rằng đây chỉ là một cuộc gọi phương thức bình thường có thể trở lại mà không ném bất kỳ ngoại lệ nào trong mọi trường hợp.

Make phương pháp này thực hiện hợp đồng ReSharper, hoặc như một cách giải quyết đơn giản (mà chỉ ảnh hưởng đến chế độ gỡ lỗi, do đó không bị phạt hiệu suất cho chế độ phát hành), ngay sau FailIfTrue gọi:

Debug.Assert(user != null); 

Điều đó sẽ thoát khỏi của cảnh báo, và như là một tiền thưởng thêm làm một kiểm tra thời gian chạy trong chế độ gỡ lỗi để đảm bảo rằng các điều kiện giả định của bạn sau khi gọi FailIfTrue thực sự là đáp ứng.

+0

Tôi ước điều đó đúng ... Resharper 5.1 không xác định chính xác 'Debug.Assert (user! = Null);' và tăng cảnh báo. Tôi có cần cấu hình gì không? –

+0

Uh, R # 5.1 là khá lỗi thời, vì vậy tôi không có gì để kiểm tra vấn đề của bạn. Tuy nhiên, một số gợi ý: Hãy chắc chắn rằng mã của bạn đúng tham chiếu đến lớp 'System.Diagnostics.Debug' như là hợp đồng mã đã được định nghĩa cho nó, và không cho các phương thức tùy ý với tên/chữ ký đó. Ngoài ra, hãy đảm bảo rằng cấu hình xây dựng được đặt thành Debug (nếu không mã này nằm ngoài phạm vi và do đó cảnh báo sẽ xuất hiện!). – Lucero

+0

'Debug.Assert' hoạt động, nhưng chỉ trong chế độ Debug. –

4

Một câu trả lời mới cho bài viết cũ ...

Dưới đây là một ít mẫu mã của tôi về cách sử dụng CodeContract qua ContractAnnotation với Resharper:

[ContractAnnotation("value:null=>true")] 
    public static bool IsNullOrEmpty(this string value) 
    { 
     return string.IsNullOrEmpty(value); 
    } 

Nó rất đơn giản ... nếu u tìm thấy mẩu bánh mì trong gỗ. Bạn cũng có thể kiểm tra các trường hợp khác.

Chúc một ngày tốt đẹp

+1

Nếu bạn biết rằng một phương pháp luôn ném một ngoại lệ, bạn có thể thực hiện '[ContractAnnotation (" => halt ")]' – Dejan

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