Bởi vì đặc tả ngôn ngữ mong đợi một biểu thức kiểu System.Exception
ở đó (do đó, null
là 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à null
hay 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 null
trườ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 null
chữ 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 null
ngoạ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 throw
lệnh. Mô tả cho lệnh đó hầu như giống với throw
câ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 throw
né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 obj
là null
.
Tính đúng đắn:
CIL đúng đảm bảo rằng đối tượng luôn luôn là một null
hoặ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
.