Cờ beforefieldinit làm gì? Khi tôi nhìn vào IL của lớp tôi thấy lá cờ này nhưng tôi không biết lá cờ này thực sự đang làm gì?Cờ beforefieldinit làm gì?
Trả lời
Xem my article về vấn đề này.
Về cơ bản, beforefieldinit
có nghĩa là "loại có thể được khởi tạo bất kỳ lúc nào trước khi bất kỳ trường tĩnh nào được tham chiếu". Trong lý thuyết có nghĩa là nó có thể được rất lười biếng khởi tạo - nếu bạn gọi một phương thức tĩnh không chạm vào bất kỳ trường nào, JIT không cần phải khởi tạo loại.
Trong thực tế nó có nghĩa là lớp được khởi tạo trước đó hơn nó sẽ khác - đó là okay cho nó được khởi tạo vào lúc bắt đầu của phương pháp đầu tiên mà thể sử dụng nó. So sánh điều này với các loại không có áp dụng beforefieldinit
cho chúng, nơi khởi tạo loại phải xảy ra ngay trước khi sử dụng thực tế đầu tiên.
Vì vậy, giả sử chúng ta có:
public static void DoSomething(bool which)
{
if (which)
{
FirstType.Foo();
}
else
{
SecondType.Bar();
}
}
Nếu cả hai loại có beforefieldinit
áp dụng cho họ (mà trong C# họ làm theo mặc định trừ loại có một constructor tĩnh) sau đó họ sẽ cả được khởi tạo vào lúc bắt đầu của phương thức (thông thường - nó không được bảo đảm). Nếu họ không có beforefieldinit
thì chỉ một trong số đó sẽ được khởi chạy, dựa trên cờ.
Đây là lý do tại sao người ta thường sử dụng một hàm tạo tĩnh (ngay cả một hàm tạo rỗng) khi implementing the singleton pattern.
Hình như nó sẽ thay đổi trong 4,6
Tuyệt vời, vậy điều này có nghĩa là nó sẽ đợi cho đến khi giây phút cuối cùng để khởi tạo trường (bất kể nó có 'beforefieldinit' hay không)? –
Trước khi sử dụng đầu tiên tất cả các truy cập sẽ được bắt đầu bằng kiểm tra khởi tạo. Sau đó, khi các phương thức khác được trích xuất, mã được tạo sẽ truy cập trực tiếp vào trường. Nếu nó là một kiểu nguyên thủy thì nó thậm chí có thể được sử dụng như một hằng số thời gian JIT. – OmariO
Phân tích chi tiết của Jon về những thay đổi về khởi tạo kiểu bắt đầu .Net 4.0 [ở đây] (https: //codeblog.jonskeet.uk/2010/01/26/type-initialization-changes-in-net-4-0 /). – RBT
- 1. Cờ fpermissive làm gì?
- 2. Cờ g ++ -D làm gì?
- 3. Cờ -f trong đuôi làm gì?
- 4. Cờ liên kết -all_load làm gì?
- 5. Cờ _REENTRANT là gì?
- 6. Biến cờ là gì?
- 7. Cờ dynamic.classpath làm gì? (Thiết lập dự án IntelliJ)
- 8. Cờ -lrt trong gnu-make là gì?
- 9. Tại sao thay đổi hành vi của BeforeFieldInit trong .NET 4?
- 10. hội - Thực cờ VS tràn cờ
- 11. Các cờ PHP trong các đối số hàm là gì?
- 12. Cờ chức năng PHP, làm cách nào?
- 13. Ý nghĩa của GFP trong cờ kmalloc là gì?
- 14. Mục đích của cờ cấu trúc trong iOS là gì?
- 15. Điều gì gây ra cờ UnhandledExceptionEventArgs.IsTerminating là đúng hay sai?
- 16. Động lực để thêm cờ IPV6_V6ONLY là gì?
- 17. Mục đích của cờ AI_V4MAPPED trong getaddrinfo là gì?
- 18. Cờ preg_match_all `u` phụ thuộc vào điều gì?
- 19. Cờ trình biên dịch Visual Studio C++: là gì -Zm200?
- 20. Kết hợp cờ -v và cờ -A trong grep
- 21. hiệu suất constructor tĩnh và lý do tại sao chúng tôi không thể xác định beforefieldinit
- 22. cờ "-g" làm gì trong lệnh "npm install -g <something>"?
- 23. Hướng cờ trong x86
- 24. cờ Enum trong JavaScript
- 25. Thuộc tính cờ Enum
- 26. Array_unique SORT_REGULAR cờ
- 27. Cờ bitwise trong Delphi
- 28. Tại sao không IgnoreCase cờ làm việc (re.I) trong re.sub()
- 29. cờ mktime và tm_isdst
- 30. Phương thức xóa cờ Thread.interrupt()
_ "loại có thể được khởi tạo tại bất kỳ điểm nào trước khi bất kỳ lĩnh vực được tham chiếu." _ Là nó cũng đúng cho việc chạy các phương pháp tĩnh? –
@RoyiNamir, thông số CLI nói rằng nếu BeforeFieldInit được áp dụng thì "phương thức khởi tạo của kiểu được thực hiện tại, hoặc đôi khi trước, lần đầu tiên truy cập vào bất kỳ trường tĩnh nào được xác định cho loại đó". Nếu thuộc tính đó bị bỏ qua (static .ctor) thì "truy cập đầu tiên vào bất kỳ trường tĩnh hoặc trường nào của kiểu đó, hoặc lần đầu tiên yêu cầu bất kỳ phương thức tĩnh, dụ hoặc ảo nào của kiểu đó". Vì vậy, nó không đúng đối với BeforeFieldInit được áp dụng trừ khi phương thức tĩnh tham chiếu đến một trường tĩnh khác. –
Tôi phát hiện ra rằng có một hình phạt hiệu suất cho việc sử dụng các hàm tạo tĩnh (tức là các lớp không có cờ beforefieldinit). Nếu bạn gọi các thành viên tĩnh của một lớp nhất định thường xuyên, có vẻ như thời gian chạy phải thực hiện kiểm tra thêm trước mỗi cuộc gọi, để kiểm tra xem kiểu đã được khởi tạo chưa; beforefieldinit tránh các kiểm tra này. Một vài điểm chuẩn nhanh hơn khoảng 50% với beforefieldinit: http://www.codeproject.com/Articles/87991/Dynamic-interfaces-in-any-NET-language – Qwertie