Khi nào một hàm tạo tĩnh được gọi trong C #?


88

Khi tôi có lớp chứa một phương thức khởi tạo tĩnh, phương thức khởi tạo đó được gọi khi hợp ngữ chứa lớp đó được tải lần đầu tiên hay khi tham chiếu đầu tiên đến lớp đó được truy cập?

Câu trả lời:


93

Khi lớp được truy cập lần đầu tiên.

Bộ tạo tĩnh (Hướng dẫn lập trình C #)

Hàm tạo tĩnh được sử dụng để khởi tạo bất kỳ dữ liệu tĩnh nào hoặc để thực hiện một hành động cụ thể chỉ cần thực hiện một lần. Nó được gọi tự động trước khi phiên bản đầu tiên được tạo hoặc bất kỳ thành viên tĩnh nào được tham chiếu.


6
Điều thú vị là nó cho biết "trước khi phiên bản đầu tiên được tạo hoặc bất kỳ thành viên tĩnh nào được tham chiếu". Có một số thời gian ở đó khi nó thực sự được gọi.
Tim Barrass

6
@TimBarrass do một số yêu cầu khác của lượt đặc điểm kỹ thuật ra rằng "trước khi" thực sự "ngay trước" - xem bài viết của Jon Skeet tham chiếu trong câu trả lời khác - stackoverflow.com/a/1437372/477420
Alexei Levenkov

A static constructor is used to initialize any static dataKHÔNG. Tốt hơn để sử dụng static initializerđể khởi tạo nội dung tĩnh.
Yousha Aleayoub

41

Nó không hoàn toàn đơn giản như bạn có thể mong đợi mặc dù tài liệu đơn giản. Bài viết của Jon Skeet http://csharpindepth.com/Articles/General/Beforefieldinit.aspx đi sâu vào câu hỏi này.

Tóm lược:

Phương thức khởi tạo tĩnh được đảm bảo sẽ được thực thi ngay trước tham chiếu đầu tiên đến một thành viên của lớp đó - hoặc là việc tạo cá thể hoặc phương thức / thuộc tính tĩnh của riêng lớp.

Lưu ý rằng các bộ khởi tạo tĩnh (nếu không có hàm tạo tĩnh) được đảm bảo sẽ được thực thi bất kỳ lúc nào trước khi tham chiếu đầu tiên đến trường cụ thể.


Bài báo đề cập tại là trên trang web của Jon Skeet: csharpindepth.com/Articles/General/Beforefieldinit.aspx
Sudhanshu Mishra

Sau câu hỏi stackoverflow.com/questions/32525628/… chứng minh trường hợp khi hành vi "ngay lập tức" là khá rõ ràng.
Alexei Levenkov

1
Tôi thực sự chỉ gặp trường hợp một phương thức khởi tạo tĩnh được gọi ngay trước khi phương thức Main của một ứng dụng console bắt đầu thực thi!
HerpDerpington

19

Hàm tạo tĩnh được gọi trước khi bạn sử dụng bất kỳ thứ gì trong lớp, nhưng chính xác khi nào điều đó xảy ra là tùy thuộc vào việc triển khai.

Nó được đảm bảo sẽ được gọi trước khi thành viên tĩnh đầu tiên được truy cập và trước khi phiên bản đầu tiên được tạo. Nếu lớp không bao giờ được sử dụng, phương thức khởi tạo tĩnh không được đảm bảo sẽ được gọi.


2
Khi điều đó xảy ra không phải là "tùy thuộc vào việc triển khai" nếu việc triển khai đó tuân theo thông số kỹ thuật ECMA C #: "Việc thực thi một hàm tạo tĩnh được kích hoạt bởi sự kiện đầu tiên xảy ra trong miền ứng dụng: [1] Một phiên bản của lớp được tạo. [2] Bất kỳ thành viên tĩnh nào của lớp đều được tham chiếu. " (Phần 17,11, ecma-international.org/publications/standards/Ecma-334.htm )
LukeH

1
@Luke: "Thời gian chính xác của việc thực thi hàm tạo tĩnh phụ thuộc vào triển khai" ondotnet.com/pub/a/dotnet/2003/07/07/staticxtor.html
Guffa

2
@Guffa: Đó có thể là cách giải thích của tác giả bài viết, nhưng bạn sẽ không tìm thấy từ ngữ đó trong phiên bản Microsoft hoặc ECMA / ISO của thông số kỹ thuật C #.
LukeH

1

Trong trường hợp phương thức static được gọi từ lớp cha, phương thức khởi tạo tĩnh sẽ không được gọi, mặc dù nó được chỉ định rõ ràng. Đây là một ví dụ phương thức khởi tạo b không được gọi nếu b.methoda () được gọi.

static void Main(string[] args)
{
    b.methoda();
}

class a
{
    public static void methoda()
    {
        //using initialized method data
    }
}

class b : a
{
    static b()
    {
        //some initialization
    }
}    

1

Có vẻ như có một gotcha với các hàm tạo tĩnh được trả lời ở nơi khác nhưng phải mất một lúc để chuyển hóa thành một lời giải thích đơn giản. Tất cả các tài liệu và giải thích đều khẳng định hàm tạo / intializer tĩnh được "đảm bảo" chạy trước khi lớp đầu tiên được khởi tạo hoặc trường tĩnh đầu tiên được tham chiếu. Gotcha xuất hiện khi bạn cố gắng đặt một singleton tĩnh trong lớp tạo ra một thể hiện của chính nó (gà / trứng). Trong trường hợp này, phương thức khởi tạo tĩnh kết thúc được gọi sau phương thức khởi tạo cá thể - và trong trường hợp của tôi, phương thức tạo cá thể chứa mã dựa trên một số dữ liệu tĩnh.

Hàm tạo tĩnh được gọi sau hàm tạo thể hiện?

Hàm tạo tĩnh có thể chạy sau hàm tạo không tĩnh. Đây có phải là lỗi trình biên dịch không?

(câu trả lời cho tôi là đặt singleton trong một lớp riêng biệt hoặc khởi tạo thủ công dữ liệu tĩnh trong phương thức khởi tạo cá thể trước khi nó được yêu cầu)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.