Mở rộng câu trả lời của Mark, khởi tạo biến cục bộ cũng liên quan đến quy trình xác minh .CLI yêu cầu rằng trong bất kỳ mã xác minh nào (có nghĩa là, các mô-đun không yêu cầu bỏ qua quá trình xác minh bằng cách sử dụng thuộc tính SkipVerfication từ thuộc tính SecurityPermission), tất cả các biến cục bộ phải được khởi tạo trước khi chúng được sử dụng. Nếu không làm như vậy sẽ dẫn đến việc bị ném VerficationException.
Thú vị hơn, là trình biên dịch tự động thêm cờ .locals init
vào mọi phương pháp sử dụng biến cục bộ. Cờ này làm cho trình biên dịch JIT tạo mã để khởi tạo tất cả các biến cục bộ thành các giá trị mặc định của chúng. Có nghĩa là, mặc dù bạn đã khởi tạo chúng trong mã của riêng bạn, JIT sẽ tuân thủ cờ .locals init
và tạo mã khởi tạo thích hợp. Điều này "khởi tạo trùng lặp" không ảnh hưởng đến hiệu suất vì trong các cấu hình cho phép tối ưu hóa, trình biên dịch JIT sẽ phát hiện sự trùng lặp và xử lý nó một cách hiệu quả là "mã chết" (thường trình khởi tạo tự động sẽ không xuất hiện trong các hướng dẫn lắp ráp được tạo).
Theo Microsoft (cũng được sao lưu bởi Eric Lippert để trả lời câu hỏi trên blog của mình), trong hầu hết các trường hợp, khi người lập trình không khởi tạo biến cục bộ của họ, họ không làm như vậy vì họ chuyển tiếp môi trường cơ bản để khởi tạo biến của chúng là giá trị mặc định, nhưng chỉ vì chúng "quên", do đó, gây ra các lỗi logic đôi khi ảo ảnh.
Vì vậy, để giảm xác suất cho các lỗi của bản chất này xuất hiện trong mã C#, trình biên dịch vẫn khẳng định bạn sẽ khởi tạo các biến cục bộ của bạn. Mặc dù nó sẽ thêm cờ .locals init
vào mã IL được tạo.
Giải thích toàn diện hơn về chủ đề này có thể được tìm thấy tại đây: Behind The .locals init Flag
Đó chỉ là lặp lại câu hỏi. Nhưng tại sao? –
@YairHalberstadt tùy thuộc vào việc "tại sao?" có nghĩa là quy tắc hoặc lý do đằng sau quy tắc. Tôi trả lời câu hỏi đầu tiên, câu trả lời cho câu hỏi; cho lần thứ hai: bởi vì vào thời điểm bạn đã xem xét việc tạo chuỗi, các phương thức ảo được gọi trong quá trình xây dựng và thực tế là các nhà xây dựng cơ sở ở cấp độ IL có thể được gọi bất kỳ lúc nào trong chuỗi cuộc gọi - hầu như không thể nói bất cứ điều gì hợp lý về khởi tạo trường; bằng nhau, các trường có thể bị chồng chéo làm cho không gian trống quan trọng hơn, do đó không yêu cầu kỹ thuật init - tương phản ... –
@YairHalberstadt biến cục bộ, có kiểm tra chuyển nhượng rất dễ dàng, nơi uninitialized thường có nghĩa là lỗi và có thể bỏ qua zeroing (mặc dù thời gian chạy hiện tại không bao giờ thực hiện, IIRC). –