2015-09-11 17 views
7

Theo nghệ thuật của Jon Skeet C# and beforefieldinit và thảo luận trong hàm xây dựng tĩnh When is a static constructor called in C#? trước khi gọi đầu tiên đến một phương thức của lớp.Tại sao hàm tạo tĩnh không được gọi trước khi gọi đầu tiên đến phương thức lớp

Đối với một số lý do sau mã số không thể hiện hành vi này:

namespace AbstractAndStatic 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      StaticClass.Equals(1,2); 
      StaticClass.foo(); 
     } 
    } 
    static class StaticClass : Object 
    { 
     public static void foo() 
     { 
      Console.WriteLine("Static"); 
     } 
     static StaticClass() 
     { 
      Console.WriteLine("static constructor"); 
     } 
    } 
    class TestClass 
    { 
     public void deb() 
     { 
      Console.WriteLine("Test Class Debug"); 
     } 
    } 
}  

Tôi gỡ lỗi mã trên bằng cách sử dụng Visual Studio Debugger. Khi tuyên bố StaticClass.Equals(1,2); được thực hiện trong phương thức chính, hàm dựng tĩnh không được gọi nhưng khi StaticClass.foo(); được thi hành, nó gọi hàm dựng tĩnh và sau đó gọi phương thức foo.

Tôi hơi bối rối vì sao nó không được gọi là lần đầu tiên khi thực hiện StaticClass.Equals(1,2);.

+0

Tôi tin rằng bạn cần ghi đè Object.Equals. Khi nó đứng, nó gọi phiên bản cơ sở. Mỗi lớp kế thừa từ đối tượng btw, do đó không cần thiết để thực hiện thủ công. –

+0

Phương thức Equals() của bạn được viết ở đâu? –

+0

@MicrosoftDN được thừa kế từ 'Object.Equals' –

Trả lời

12

Cuộc gọi của bạn để StaticClass.Equalsthực chỉ là một cuộc gọi đến Object.Equals(Object, Object), như StaticClass không cung cấp một quá tải áp dụng cho Equals. Nếu bạn nhìn vào IL, bạn sẽ thấy rằng trình biên dịch đã giải quyết cuộc gọi đến chỉ Object.Equals(1, 2). Nếu bạn không gọi một phương thức thực sự liên quan đến lớp tĩnh, nó không cần phải được khởi tạo.

+0

Lưu ý rằng "nó không * cần * được khởi tạo" - nó vẫn sẽ là hành vi hợp lệ nếu khung công tác quyết định gọi hàm dựng tĩnh trước đó. –

+2

@AlexeiLevenkov: Không, không. Nếu một kiểu có một hàm tạo tĩnh, nó được đảm bảo rằng nó chỉ được thực thi * ngay lập tức * trước tham chiếu đầu tiên tới một thành viên của lớp đó. Bạn có thể suy nghĩ về khi một loại mà không có một constructor tĩnh được khởi tạo, đó là đáng kể hơn khoan dung. Cụ thể, từ thông số C#: "Việc thực hiện một hàm tạo tĩnh được kích hoạt bởi sự kiện đầu tiên trong số các sự kiện sau xảy ra trong miền ứng dụng: \t Một cá thể của loại lớp được tạo. \t Bất kỳ thành phần tĩnh nào của loại lớp được tham chiếu. " –

+0

@AlexeiLevenkov: Xem thêm: http://csharpindepth.com/Articles/General/Beforefieldinit.aspx –

Các vấn đề liên quan