2010-07-01 30 views
5

Lớp tĩnh nào khởi tạo đầu tiên nếu chúng ta có thêm một lớp tĩnh trong dự án của chúng ta?Lớp tĩnh nào khởi tạo trước tiên?

Ví dụ: Mã bên dưới cung cấp ngoại lệ cho null.

class Program 
    { 
     static void Main(string[] args) 
     { 
      First.Write(); 
      Second.Write(); 
     } 
    } 
    static class First 
    { 
     public static int[] firstArray = new int[20]; 
     public static int[] secondArray = Second.secondArray; 
     public static void Write() 
     { 
      Console.WriteLine(firstArray.ToString()); 
      Console.WriteLine(secondArray.ToString()); 
     } 
    } 
    static class Second 
    { 
     public static int[] firstArray = First.firstArray; 
     public static int[] secondArray = new int[30]; 
     public static void Write() 
     { 
      Console.WriteLine(firstArray.ToString()); 
      Console.WriteLine(secondArray.ToString()); 
     } 
    } 

Nếu bạn chú ý, bạn sẽ thấy rằng nếu First lớp sẽ khởi tạo bản thân để secondArray lĩnh vực Second sẽ là null. Nhưng nếu Second lớp sẽ khởi tạo trước tiên thì Second lớp firstArray sẽ là rỗng. Tôi đang cố gắng để nói rằng khởi tạo đầu tiên làm cho kết quả khác nhau.

Tôi nghĩ rằng đó là câu hỏi trừu tượng về dự án của tôi. Tôi gặp nó trong khi cố gắng hiểu tại sao tôi lại nhận được kết quả bất ngờ.

Trả lời

10

First sẽ bắt đầu khởi tạo, chuyển nhượng firstArray, sau đó nhận thấy rằng nó đòi hỏi Second được khởi tạo để có được giá trị ban đầu của secondArray.

Second sẽ bắt đầu khởi chạy và sau đó nhận thấy rằng nó yêu cầu Trước tiên phải được khởi tạo. Tuy nhiên, CLR sau đó sẽ thông báo rằng Đầu tiên là đã khởi chạy trong chuỗi hiện tại, vì vậy nó sẽ không chặn. Second Quá trình khởi tạo sẽ hoàn tất, sau đó khởi tạo lần đầu tiên sẽ hoàn tất.

May mắn thay, trường mà nhu cầu Second đã được gán, do đó, "điều đúng" sẽ xảy ra.

Đó là tất cả rất tốt nếu Firstthực sự bắt đầu khởi chạy trước tiên. Tuy nhiên, vì không có lớp nào có hàm tạo tĩnh, có thể là Second sẽ bắt đầu khởi tạo trước tiên ... sau đó nó sẽ bắt đầu khởi tạo First, sẽ phát hiện rằng Second đã khởi tạo và lấy giá trị hiện tại Second.secondArray (null) cho First.secondArray. Đây sẽ là một điều xấu. Lưu ý rằng thời gian khởi tạo cho các kiểu không có các hàm tạo tĩnh có changed in .NET 4 - không theo cách phân tích, nhưng có thể theo cách phá vỡ mã hiện có.

Nếu cả hai FirstSecond đều có các hàm tạo tĩnh, thì First sẽ được khởi tạo trước tiên, vì đó là lớp đầu tiên có các chạm là Main.

Đạo đức của câu trả lời: không làm điều này. Loại initializers tham chiếu với nhau rất dễ bị lỗi. Ví dụ khác, xem Eric Lippert và NDC 2010 của Neal Gafter nói chuyện, "C# Puzzlers" có thể được xem trên NDC video page.

+0

Liệu bảo lãnh tiêu chuẩn thứ tự này? Đoán của tôi là mỗi lớp khởi tạo ở một số không xác định trước khi truy cập đầu tiên, mà biến điều này thành một chu kỳ phụ thuộc được giải quyết ngẫu nhiên. –

+0

@Tim: Tôi đã cập nhật câu trả lời của mình - không có nhà thầu tĩnh, thứ tự thực sự không được xác định. –

+0

Với trình gỡ rối gắn liền với VS2005, một điều xấu xảy ra - 'Second.firstArray' được đặt thành' null' – AakashM

0

Tôi không tin rằng có bất kỳ sự đảm bảo nào về loại tĩnh được khởi tạo trước tiên. Để đảm bảo các lĩnh vực đang được khởi tạo đúng cách này, bạn sẽ cần phải thêm một constructor tĩnh, ví dụ:

static class Second 
{ 
    public static int[] firstArray = First.firstArray; 
    public static int[] secondArray = new int[30]; 

    static Second() { } 

    public static void Write() 
    { 
     Console.WriteLine(firstArray.ToString()); 
     Console.WriteLine(secondArray.ToString()); 
    } 
} 

Bây giờ, khi bạn chạy điều tương tự một lần nữa, nó hoạt động ...

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