Tôi chắc chắn sẽ lập luận rằng có một lỗ hổng trong thiết kế nếu bạn cảm thấy cần phải ném ngoại lệ từ một trình thiết lập hoặc getter thuộc tính.
Một tài sản là một sự trừu tượng đại diện cho một cái gì đó chỉ là một giá trị . Và bạn sẽ có thể đặt giá trị mà không sợ rằng làm như vậy có thể tạo ra ngoại lệ. *
Nếu thiết lập các kết quả thuộc tính trong một hiệu ứng phụ, điều đó thực sự nên được thực hiện như một phương pháp thay thế. Và nếu nó không tạo ra bất kỳ tác dụng phụ nào, thì không nên ném ngoại lệ.
Một ví dụ đã được đề cập trong một câu trả lời khác nhau là Stream.Positiontài sản. Điều này không tạo ra tác dụng phụ, và có thể ném ngoại lệ. Nhưng trình thiết lập thuộc tính này về cơ bản chỉ là một trình bao bọc Stream.Seekmà bạn có thể gọi thay thế.
Cá nhân, tôi tin rằng vị trí không nên là một tài sản có thể ghi.
Một ví dụ khác mà bạn có thể muốn đưa ra một ngoại lệ từ trình thiết lập thuộc tính là trong việc xác thực dữ liệu:
public class User {
public string Email {
get { return _email; }
set {
if (!IsValidEmail(value)) throw InvalidEmailException(value);
_email = value;
}
}
Nhưng có một giải pháp tốt hơn cho vấn đề này. Giới thiệu một loại đại diện cho một địa chỉ email hợp lệ:
public class Email {
public Email(string value) {
if (!IsValidEmail(value)) throw new InvalidEmailException(value);
...
}
...
}
public class User {
public Email Email { get; set; }
}
Các EmailĐảm bảo lớp mà nó không thể giữ một giá trị không phải là một địa chỉ email hợp lệ, và các lớp học mà cần phải email lưu trữ được giải phóng khỏi nhiệm vụ chứng thực họ.
Điều này cũng dẫn đến sự gắn kết cao hơn (một chỉ số về thiết kế phần mềm tốt) - kiến thức về địa chỉ email là gì và cách xác thực, chỉ tồn tại trong Emaillớp, chỉ có mối quan tâm đó.
* ObjectDisposedException là ngoại lệ hợp lệ duy nhất (không có ý định chơi chữ) tôi có thể nghĩ đến vào lúc này.