2012-02-17 32 views
7

thể trùng lặp:
What is the static variable initialization order in C#?Các quy tắc để khởi tạo thứ tự trong C# là gì?

Đối với niềm vui tôi chạy this code

Tôi đã không mong đợi 2 2 3. Tôi đã mong đợi một lỗi trình biên dịch (phụ thuộc circlur) hoặc 8 5 3.

Quy tắc khởi tạo thứ tự trong C# là gì?

-edit- i tried making a not static và tôi đã nhận được những gì tôi mong đợi. Tại sao là b 2 trước và bây giờ 5. Tôi không nghĩ rằng tôi sẽ thích các quy tắc ... May mắn thay tôi không bao giờ làm bất cứ điều gì như thế này vì vậy tôi đã không có một vấn đề.

using System; 

public class Test 
{ 
     public static void Main() 
     { 
       A.t(); 
     } 
} 

class A 
{ 
    static int a = B.b + c; 
    public static int c = 3; 
    static public void t() 
    { 
     Console.WriteLine("{0} {1} {2}", a, B.b, c); 
    } 
} 
class B 
{ 
    public static int b = A.c+2; 
} 
+1

Nếu bạn nghĩ điều đó thật thú vị: hãy tưởng tượng bạn có các lớp học một phần, vì vậy không có thứ tự văn bản được xác định: http://stackoverflow.com/questions/7965830/is-the-textual-order-across-partial- các lớp được định nghĩa chính thức –

Trả lời

5

Việc khởi tạo là mỗi loại khi cần thiết (trước khi xảy ra trường hợp này). Withing một lớp học: "trật tự văn bản":

§17.11 trong ECMA 334:

Nếu một lớp có chứa bất kỳ lĩnh vực tĩnh với initializers, những initializers được thực hiện theo thứ tự văn bản ngay trước khi thực hiện các constructor tĩnh.

Nó không áp dụng cho các trường mẫu, vì bạn không thể sử dụng giá trị mẫu trong trình khởi tạo trường.

+0

Cách thức hoạt động với các phụ thuộc vòng tròn? – Cameron

+0

@Cameron rõ ràng là không cố gắng. Nó xử lý chúng theo "thứ tự văn bản", I.e. từ trên xuống dưới. –

+0

Người quay phim nói gì. Có vẻ như một khi nó vào "A" nó không cố gắng khởi tạo 'c' khi B.b cố gắng truy cập nó. Nhưng tôi tin rằng tôi hiểu cách nó hoạt động. (proibably sẽ chấp nhận câu trả lời này) -edit- thấy điểm chung của bạn. Oh. tôi không đoán được. Thật không may. mono và ms cho cùng một kết quả tho tốt. –

0

-edit- tôi biết tôi đã sử dụng tĩnh nhưng vui lòng giải thích không tĩnh. Tôi sẽ kiểm tra với nonstatic trong một phút

Bạn không gặp vấn đề này với các trường không tĩnh vì bạn không thể đọc trường mẫu của đối tượng chưa được tạo.

+0

poke xem chỉnh sửa/mã số –

2

Nếu tôi là bạn, tôi luôn luôn giả định rằng trình biên dịch của bạn khởi tạo biến theo thứ tự ngẫu nhiên (không xác định).

Nhân tiện, static biến được liên kết với lớp học của bạn và không phải bất kỳ phiên bản nào của lớp học của bạn. chúng chủ yếu là các biến toàn cục.

+1

Đó là một giả định rất tốt thường. Mặc dù thứ tự IS được chỉ định trong spec, thực tế rất xấu (IMO) dựa vào thứ tự khởi tạo. Nó làm cho mã của bạn hoàn toàn không thể đọc được, và tôi dường như không thể nghĩ ra một lý do duy nhất tại sao bạn sẽ làm điều này bình thường. –

2

Việc khởi chạy diễn ra theo thứ tự nó xuất hiện trong một lớp học. Vì vậy, đây là những gì đang xảy ra ở đây:

  1. A được khởi tạo. Nó bắt đầu thiết lập A.a nhưng cần B, vì vậy ...
  2. B được khởi tạo. B.b được thiết lập - A.c là hợp lệ nhưng chưa được khởi tạo, vì vậy nó là 0. B.b trở thành 2.
  3. A.a được đặt thành B.b (2) + c (chưa được đặt - vì vậy 0). A.a bây giờ là 2.
  4. Cuối cùng, c được đặt thành 3.
+0

Đó là những gì tôi giả định sau khi tôi chỉnh sửa/thử nghiệm thứ 2. Tôi không thích ý tưởng đó. Tôi thay vì nhận được một lỗi biên dịch: x –

3

Tất cả đều có ý nghĩa hoàn hảo.Đây là chuỗi các sự kiện:

  1. Bạn gọi A.t
  2. Vì đây là việc sử dụng đầu tiên của A, các thành viên tĩnh của nó a được khởi tạo để B.b + c
    • Vì đây là việc sử dụng đầu tiên của B, nó thành viên tĩnh b được khởi tạo thành A.c+2. Đây là không phải lần sử dụng đầu tiên của A, vì vậy, hãy đọc trực tiếp A.c. Vì nó chưa được khởi tạo tĩnh, nó vẫn được đặt thành giá trị mặc định là 0. Do đó B.b trở nên 2.
    • Tại thời điểm này, A 'initializer tĩnh s thêm 2 B.b-0 từ A' s riêng c, mà vẫn thiết lập giá trị mặc định của 0.
  3. Chuỗi intialization tĩnh tiếp tục với cài đặt A.c đến 3.
  4. Bây giờ A đã sẵn sàng để sử dụng và t() tiến hành in 2 2 3, theo các giá trị được lưu trữ trong các trường tương ứng của AB.
+0

Đó là những gì tôi giả định sau khi tôi chỉnh sửa/thử nghiệm thứ 2. Tôi không thích ý tưởng đó. Tôi thay vì nhận được một lỗi biên dịch: x –

+2

@ acidzombie24 Tôi đồng ý, khởi tạo tĩnh như vậy là ác. – dasblinkenlight

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