2009-04-27 27 views
38

Tôi muốn để người lập trình và bản thân biết rằng phương pháp không muốn null và nếu bạn gửi null cho dù sao thì kết quả sẽ không đẹp.C#: Cách triển khai và sử dụng thuộc tính NotNull và CanBeNull

Có một NotNullAttributeCanBeNullAttribute trong Lokad Shared Libraries, trong không gian tên Lokad.Quality.

Nhưng cách thức hoạt động? Tôi đã xem mã nguồn của hai thuộc tính đó và trông giống như sau:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | 
       AttributeTargets.Property | AttributeTargets.Delegate | 
       AttributeTargets.Field, AllowMultiple = false, Inherited = true)] 
[NoCodeCoverage] 
public sealed class NotNullAttribute : Attribute 
{ 
} 

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | 
       AttributeTargets.Property | AttributeTargets.Delegate | 
       AttributeTargets.Field, AllowMultiple = false, Inherited = true)] 
[NoCodeCoverage] 
public sealed class CanBeNullAttribute : Attribute 
{ 
} 

Hai lớp trống kế thừa từ Attribute. Chúng được sử dụng như thế nào? Bạn có phải tìm kiếm tài liệu xml và biết rằng nó có ở đó không? Vì tôi đã cố tạo cả bản sao thuộc tính của riêng mình và sử dụng phiên bản Lokad, nhưng khi tôi cố gắng gửi một null trực tiếp vào, tôi không nhận được thông báo nào. Không phải từ ReSharper cũng như từ VS. Tôi thực sự mong đợi điều đó. Nhưng chúng được sử dụng như thế nào? Tôi có thể bằng cách nào đó làm cho VS tạo ra cảnh báo cho tôi nếu tôi cố gắng gửi một cái gì đó là null trong đó? Hoặc là nó chỉ được sử dụng trong một số loại khuôn khổ thử nghiệm? Hoặc là?

+1

Để nhận xét về trường hợp cụ thể của bạn, những thuộc tính đó không làm bất cứ điều gì và chỉ là "tài liệu". Tuy nhiên, các câu trả lời khác cung cấp giải pháp thay thế tốt. – Sander

+3

'Nullable' là tên tốt hơn cho' CanBeNull', chỉ cần nói :) –

Trả lời

46

Trong trung hạn, "hợp đồng mã" (trong 4.0) sẽ là câu trả lời hay hơn cho điều này. Hiện có sẵn (với academic hoặc commercial giấy phép), nhưng sẽ được tích hợp nhiều hơn trong VS2010. Điều này có thể cung cấp cả phân tích tĩnh và hỗ trợ thời gian chạy.

(chỉnh sửa) ví dụ:

Contract.RequiresAlways(x != null); 

đơn giản như ... động cơ hợp đồng đang làm việc ở cấp IL, vì vậy nó có thể phân tích đó và ném cảnh báo/lỗi từ gọi mã trong xây dựng, hoặc ít thời gian chạy. Đối với khả năng tương thích ngược, nếu bạn đã mã xác nhận hiện tại, bạn có thể chỉ nói với nó nơi sự tỉnh táo kiểm tra kết thúc, và nó sẽ làm phần còn lại:

if (x == null) throw new ArgumentNullException("x"); 
Contract.EndContractBlock(); 
+0

Điều đó trông rất mượt mà! Nó có hoạt động trong VS 2008 không? Bạn có ý nghĩa gì bởi "tích hợp hơn"? – Svish

+0

Có; các liên kết tôi đã đăng là phiên bản VS2008. Bởi "tích hợp hơn", tôi có nghĩa là AFAIK, nó được xây dựng trong IDE và thời gian chạy, chứ không phải là một phần bổ sung riêng biệt. Tôi đã không kiểm tra (thực sự, không thể) - nhưng điều này * có thể * có thể có nghĩa là nó hoạt động trong Express Edition quá (add-on không). –

+0

Tuyệt. Bạn đã thử tiện ích bổ sung này chưa? Dễ cài đặt và sử dụng? Có an toàn để sử dụng trong môi trường sản xuất không? (Liệu các nhân viên khác sẽ giết tôi nếu tôi thêm nó? P) – Svish

18

Điều này có thể được thực hiện hoặc với AOP, theo đó một lời khuyên xác minh tại thời gian chạy cho dù tham số phương thức là null và có cho phép null hay không. Xem PostSharpSpring.NET cho AOP.

Đối với ReSharper, xem Annotated Framework:

Chúng tôi đã phân tích một phần lớn của .NET Framework Class Library, cũng như NUnit Framework, và chú thích nó thông qua các file XML bên ngoài, sử dụng một tập hợp các thuộc tính tùy chỉnh từ JetBrains.Chú thích không gian tên, cụ thể:

  • StringFormatMethodAttribute (đối với phương pháp mà mất dạng chuỗi như thông số)
  • InvokerParameterNameAttribute (đối với phương pháp với chuỗi lập luận theo nghĩa đen mà phải phù hợp với một trong các thông số người gọi)
  • AssertionMethodAttribute (đối với phương pháp khẳng định)
  • AssertionConditionAttribute (cho thông số điều kiện của phương thức xác nhận)
  • TerminatesProgramAttribute (cho phương pháp chấm dứt luồng điều khiển)
  • CanBeNullAttribute (đối với giá trị có thể được null)
  • NotNullAttribute (cho các giá trị mà không thể được null)
+0

Bạn có thể nhận được các chú thích ReSharper từ NuGet : https://www.nuget.org/packages/JetBrains.Annotations/ – aboy021

+3

Nhưng chú thích chia sẻ lại chỉ là một chú thích có thể đọc được để resharper .. chúng không được kiểm tra khi chạy – Revious

3

Như đã chỉ bởi Anton Gogolev, thuộc tính có thể được tạo ra sử dụng PostSharp. (Lưu ý rằng CodeContract đang sử dụng phương pháp tĩnh gọi bên trong cơ thể của phương pháp)

CẬP NHẬT tháng 2 năm 2013: phát hành 3.0 mới của PostSharp (hiện đang trong Beta) sẽ hỗ trợ Validating parameters, fields and properties

1) Điều validate-parameters-using-attributes có thực hiện

public class NotEmpty: ParameterAttribute

public class notnull: ParameterAttribute

[AttributeUsage (AttributeTargets.Parameter)]

public abstract class ParameterAttribute: Thuộc tính

{

public abstract void CheckParameter(ParameterInfo parameter, object value); 

}

Nó cũng buộc một thuộc tính phương pháp với một khía cạnh phương pháp ranh giới để xử lý các thuộc tính tham số.

2) Trong bình luận cho bài viết có liên kết đến very similar implementation cho NonNull/rỗng

[trở lại: NonNull] public SomeObject SomeMethod ([NonNull] AnotherObject param1)

Các mã nguồn nằm ở google code Torch/DesignByContract

3) một ví dụ phức tạp khác được mô tả trong http://badecho.com/2011/11/validating-method-parameters-with-postsharp/

6

Các chú thích này dành cho ReSharper và được sao chép từ không gian tên JetBrains.Annotations. Một khung công tác có thể đặt chúng trong không gian tên riêng của chúng, tuy nhiên, ReSharper sẽ KHÔNG tự động nhận các chú thích này - bạn cần phải báo cho ReSharper sử dụng không gian tên tùy chỉnh trong hộp thoại tùy chọn. Khi bạn đã chọn không gian tên mới, phân tích của ReSharper sẽ nhận các thuộc tính và cung cấp cho bạn những điểm nổi bật và cảnh báo.

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