Bởi vì đặc tả ngôn ngữ mong đợi một biểu thức kiểu System.Exceptionở đó (do đó, nulllà hợp lệ trong ngữ cảnh đó) và không hạn chế biểu thức này là khác rỗng. Nói chung, không có cách nào nó có thể phát hiện ra giá trị của biểu thức đó có phải là nullhay không. Nó sẽ phải giải quyết vấn đề tạm dừng. Thời gian chạy sẽ phải giải quyết nulltrường hợp nào. Xem:
Exception ex = null;
if (conditionThatDependsOnSomeInput)
ex = new Exception();
throw ex;
Tất nhiên, họ có thể làm cho trường hợp cụ thể của việc ném nullchữ không hợp lệ nhưng điều đó sẽ không giúp ích nhiều, vậy tại sao lại lãng phí không gian đặc tả và giảm tính nhất quán vì ít lợi ích?
Tuyên bố từ chối trách nhiệm (trước khi tôi bị Eric Lippert tát): Đây là suy đoán của riêng tôi về lý do đằng sau quyết định thiết kế này. Tất nhiên, tôi chưa tham gia cuộc họp thiết kế;)
Câu trả lời cho câu hỏi thứ hai của bạn, liệu một biến biểu thức được bắt trong mệnh đề bắt có bao giờ có giá trị không: Trong khi đặc tả C # không nói về việc liệu các ngôn ngữ khác có thể gây ra một nullngoại lệ được truyền hay không, nó xác định cách các ngoại lệ được truyền:
Các điều khoản bắt, nếu có, được kiểm tra theo thứ tự xuất hiện để xác định vị trí xử lý phù hợp cho ngoại lệ. Mệnh đề bắt đầu tiên chỉ định kiểu ngoại lệ hoặc kiểu cơ sở của kiểu ngoại lệ được coi là một kết quả khớp. Một mệnh đề bắt chung được coi là phù hợp với bất kỳ loại ngoại lệ nào. [...]
Vì null, tuyên bố in đậm là sai. Vì vậy, mặc dù hoàn toàn dựa trên những gì đặc tả C # nói, chúng ta không thể nói rằng thời gian chạy cơ bản sẽ không bao giờ ném giá trị rỗng, chúng ta có thể chắc chắn rằng ngay cả khi đúng như vậy, nó sẽ chỉ được xử lý bởi catch {}mệnh đề chung .
Để triển khai C # trên CLI, chúng ta có thể tham khảo thông số kỹ thuật ECMA 335. Tài liệu đó xác định tất cả các ngoại lệ mà CLI ném vào bên trong (không có ngoại lệ nào null) và đề cập rằng các đối tượng ngoại lệ do người dùng xác định được ném bởi throwlệnh. Mô tả cho lệnh đó hầu như giống với throwcâu lệnh C # (ngoại trừ việc nó không hạn chế kiểu của đối tượng System.Exception):
Sự miêu tả:
Lệnh throwném đối tượng ngoại lệ (kiểu O) trên ngăn xếp và làm trống ngăn xếp. Để biết chi tiết về cơ chế ngoại lệ, hãy xem Phân vùng I.
[Lưu ý: Trong khi CLI cho phép ném bất kỳ đối tượng nào, CLS mô tả một lớp ngoại lệ cụ thể sẽ được sử dụng cho khả năng tương tác ngôn ngữ. ghi chú cuối]
Các trường hợp ngoại lệ:
System.NullReferenceExceptionđược ném nếu objlà null.
Tính đúng đắn:
CIL đúng đảm bảo rằng đối tượng luôn luôn là một nullhoặc một tham chiếu đối tượng (tức là thuộc loại O).
Tôi tin rằng những điều này là đủ để kết luận các trường hợp ngoại lệ bị bắt là không bao giờ null.