2011-01-25 33 views
9

Tôi thực sự đang cố gắng tìm ra các phương pháp hay nhất để sử dụng lại mã có thể dễ dàng được gỡ lỗi. Tôi đã chạy vào một thực tế phổ biến giữa các nhà phát triển mà tôi chưa hiểu lắm.Kiểm tra Null trong Constructor

public MyConstructor(Object myObject) 
{ 
    if (myObject == null) 
     throw new ArgumentNullException("myObject is null."); 
    _myObject = myObject; 
} 

Có vẻ như không cần thiết để thực hiện kiểm tra này. Nhưng tôi nghĩ rằng đó là bởi vì tôi không hoàn toàn hiểu những lợi ích của việc kiểm tra này là gì. Nó có vẻ như một ngoại lệ tham chiếu null sẽ được ném anyway? Tôi có lẽ sai, thực sự muốn nghe một số suy nghĩ về nó.

Cảm ơn bạn.

+0

Những gì bạn đang làm là không cần thiết, bạn có thể kiểm tra để đảm bảo trước khi bạn tham chiếu đối tượng, rằng nó không phải là null. Tất nhiên xác nhận những gì bạn sẽ được sử dụng khi đối tượng của bạn là intialized là một cách tiếp cận rất hợp lệ. –

+2

@Ramhound - đây là một cách tiếp cận phổ biến khi sử dụng các khung công tác DI như StructureMap, nơi bạn không nhất thiết có quyền kiểm soát trực tiếp những gì được truyền vào hàm tạo. Nếu lớp của bạn là vô ích nếu không có 'myObject' và đây là nơi duy nhất để khởi tạo nó thì sẽ có ý nghĩa khi ném các ngoại lệ càng sớm càng tốt để bạn biết về chúng. Trong một ứng dụng web chạy dài, bạn có thể không biết về vấn đề này cho đến khi ai đó xảy ra gọi một phương thức yêu cầu đối tượng. –

Trả lời

17

Để trình biên dịch, null là đối số công cụ hợp pháp.

Lớp học của bạn có thể xử lý một giá trị null cho myObject. Nhưng nếu nó không thể - nếu lớp học của bạn sẽ phá vỡ khi myObject là null - sau đó kiểm tra trong constructor cho phép bạn fail fast.

+0

Rất tốt giải thích. Tôi đặc biệt thích thuật ngữ "thất bại nhanh". Cảm ơn bạn vì những hiểu biết. – jsmith

+2

+1 Wow, đó là một bài báo tuyệt vời. Cảm ơn các liên kết. –

1

Trình biên dịch không có ý tưởng về giá trị của một đối tượng, vì vậy bạn phải kiểm tra điều này khi chạy để đảm bảo nó không được gọi với giá trị rỗng.

Nó cũng tùy thuộc vào giải pháp cụ thể của bạn. Bạn không cần phải ném ngoại lệ, tôi sẽ chỉ ném nó nếu bạn không thể có giá trị đó là null, và nếu nó là null, đó là một trường hợp ngoại lệ.

1

Tôi nghĩ rằng nó không thể nói chung cho dù kiểm tra cho null là cần thiết hay không. Nó phụ thuộc vào việc bạn có thể sống với các biến có giá trị null hay không. Null không phải là một tình trạng xấu. Bạn có thể có các tình huống mà nó được cho phép cho một biến là null và khác ở nơi nó không phải là.

Tự hỏi liệu có nên cho phép giá trị null hay không và thiết kế hàm tạo tương ứng.

3

Việc chuyển đối tượng null hoàn toàn hợp pháp trong nhiều trường hợp - đối với lớp này người triển khai muốn đảm bảo rằng bạn không thể tạo cá thể của lớp bằng cách chuyển trường hợp Object hợp lệ, vì vậy không phải kiểm tra sau on - đó là một thực hành tốt để đảm bảo điều này càng sớm càng tốt, mà sẽ có trong constructor.

0

Bạn cần kiểm tra rõ ràng null vì trình biên dịch không biết, nhưng cũng vì null có thể là đối số hợp lệ.

0

Lợi ích là ngoại lệ sẽ được ném vào thời điểm xây dựng đối tượng, vì vậy bạn có thể dễ dàng theo dõi phần nào của mã là thủ phạm. Nếu mã của bạn yêu cầu không null giá trị myobject và bạn không xác nhận nó trong các nhà xây dựng, các NullReferenceException sẽ được ném ra khi bạn sử dụng myObject_ và bạn sẽ phải tìm lại bằng tay để xem ai gửi mà giá trị null trong.

1

Bạn có thể triển khai phương thức mở rộng đơn giản ThrowIfNull để giảm mã bạn viết mỗi lần. Jon Skeet đã đề cập đến điều này trong số blog của mình và bài viết SO được tham chiếu here.

+0

Liên kết blog bị hỏng, nhưng tôi đoán đây là cùng một bài viết: http://codeblog.jonskeet.uk/2009/12/09/quot-magic-quot-null-argument-testing/comment-page-1/ –

2

nếu bạn dưới 4.0, bạn có thể làm như sau:

public ctor(IEnjection ninjaWeapon) 
{ 
    Contract.Requires<ArgumentNullException>(ninjaWeapon != null); 
    this.deadlyWeaponary.Add(ninjaWeapon); 
} 

nếu bạn theo một phiên bản cũ, tham khảo các Microsoft.Contract để làm điều tương tự.

+1

+1 để sử dụng ninjaWeapon – ninjasense

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