2009-07-10 24 views
17

tôi không biết bao nhiêu lần không biết bao nhiêu Tôi đã phải viết mã để xác nhận đối số chuỗi:C#: Đối số xác nhận: null/chuỗi rỗng

public RoomName(string name) 
{ 
    if (string.IsNullOrEmpty(name)) 
    { 
     throw new ArgumentException("Cannot be empty", "name"); 
    } 
} 

Liệu có cách nào để tránh điều này? Có một số cơ chế thuộc tính hoặc thiết kế theo hợp đồng để tránh điều này không? Không có cách nào để nói:

public RoomName(NotNullOrEmptyString name) 
{ 

mà không phải thực sự tạo loại đó?

+0

Bạn có thể tìm thấy liên kết này trên [Xác thực đối số bằng cách sử dụng thuộc tính và chặn phương pháp] (http://www.codinginstinct.com/2008/05/argument- validation-using-attributes.html) hữu ích – Joe

Trả lời

7

Bạn có thể thực hiện điều đó thông qua việc thêm mã với các thuộc tính.

Một tùy chọn khác để tiết kiệm thời gian mã hóa, nhưng vẫn cung cấp cho bạn nhiều quyền kiểm soát, sẽ sử dụng một cái gì đó như CuttingEdge.Conditions. Điều này cung cấp giao diện thông thạo để kiểm tra đối số, vì vậy bạn có thể viết:

name.Requires().IsNotNull(); 
1

Mặc dù câu hỏi đã được trả lời cách đây một thời gian, tôi đã suy nghĩ về cùng một vấn đề gần đây. Các hợp đồng mã được chính thức hóa (với xác minh tự động hoặc kiểm tra) có vẻ là một ý tưởng hay, nhưng nhìn chung, khả năng xác minh của chúng khá hạn chế và đối với các kiểm tra đơn giản như kiểm tra chuỗi rỗng hoặc rỗng, chúng yêu cầu nhiều mã (hoặc nhiều hơn)) so với séc cũ.

Trớ trêu thay, câu trả lời hay nhất trong trường hợp chuỗi thực sự là một hoặc hai lớp bọc một chuỗi đã được kiểm tra không rỗng, trống hoặc không gian trắng và chuyển thể hiện này xung quanh:

public class NonEmptyString : IComparable<NonEmptyString>, ... 
{ 
    private readonly string _value; 

    public NonEmptyString(string value) 
    { 
     if (value == null) 
     { 
      throw new ArgumentNullException("value"); 
     } 
     if (value.Length == 0) 
     {     
      throw NewStringIsEmptyException("value"); 
     } 
     _value = value; 
    } 

    public string Value 
    { 
     get { return _value; } 
    } 

    ... 
} 

public class NonWhiteSpaceString : NonEmptyString 
{ 
    .... 
} 

chắc chắn, đi xung quanh những trường hợp này không ngăn cản bạn từ việc phải kiểm tra xem họ đang là null mình, nhưng nó có một số lợi thế lớn:

  • bạn không cần phải kiểm tra rỗng hoặc White- chuỗi không gian lặp đi lặp lại, có thể dễ bị lỗi trong các tình huống mà chuỗi được truyền đi rất nhiều.
  • Như tôi đã làm trong quá trình thực hiện, kiểm tra null là khác với kiểm tra giá trị rỗng (hoặc giá trị khoảng trống), vì bạn muốn ném một ArgumentNullException cụ thể trong trường hợp cũ và một số ArgumentException trong lần thứ hai.
  • Báo cáo rõ ràng ràng buộc về giá trị của chuỗi, giống như bất kỳ lớp gói nào được cho là phải làm. Trong thực tế, nếu bạn có một chuỗi có bất kỳ ràng buộc nào và nó được truyền xung quanh rất nhiều, tôi luôn khuyên bạn nên bọc nó trong một lớp đóng gói kiểm tra và giữ phần còn lại của mã không gặp rắc rối. Một ví dụ điển hình cho việc này là các chuỗi phải đáp ứng một cụm từ thông dụng nhất định. Tuy nhiên, tôi chuyển hướng từ câu hỏi ở đây ...
+1

Tôi nghĩ bạn cần phải thêm một số theo dõi tên tham số vào giải pháp của mình. Điều này là do hầu hết mọi người sẽ thấy khó hiểu nếu bạn gọi 'frob (chuỗi foo, chuỗi bar)' với 'frob (null," a value ")' và nhận được thông báo lỗi 'System.ArgumentNullException: Value không thể là null. Tên tham số: giá trị' thay vì 'System.ArgumentNullException: Giá trị không được rỗng. Tên thông số: foo' –

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