2009-10-29 36 views
18

Là một newbie tương đối, tôi cố đọc nhiều nhất có thể về một chủ đề cụ thể và kiểm tra/viết nhiều mã nhất có thể. Tôi đang xem một trong số Jons Brainteasers (câu hỏi # 2) và đầu ra của tôi khác với câu trả lời. Mà làm cho tôi đến đây để hỏi xem có cái gì đó đã thay đổi trong các phiên bản gần đây và để xem những gì người khác nhận được từ mã này.Sử dụng hàm tạo tĩnh (Jon Skeet Brainteaser)

Câu hỏi đặt ra là "Điều gì sẽ được hiển thị, tại sao và bạn tự tin như thế nào?"

using System; 

class Foo 
{ 
    static Foo() 
    { 
     Console.WriteLine ("Foo"); 
    } 
} 

class Bar 
{ 
    static int i = Init(); 

    static int Init() 
    { 
     Console.WriteLine("Bar"); 
     return 0; 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     Foo f = new Foo(); 
     Bar b = new Bar(); 
    } 
} 

Điều gì sẽ xảy ra nếu chúng tôi có hai câu trả lời khác nhau?

+1

Bạn đang hỏi "nếu có điều gì đó đã thay đổi trong các phiên bản gần đây của Visual Studio". Những gì bạn đang thực sự yêu cầu sẽ là nếu bất cứ điều gì thay đổi trong phiên bản mới hơn của .NET Framework. Và, thực sự không có gì lớn sẽ thay đổi từ phiên bản sang phiên bản, vì nó sẽ là một thay đổi lớn lao. –

+1

Đã sao chép. Hấp dẫn. –

+3

Vâng, câu trả lời của bạn là gì? –

Trả lời

24

Bây giờ hãy thử ở chế độ phát hành, bên ngoài trình gỡ lỗi ;-p

Tôi nhận được các kết quả khác nhau có/không có trình gỡ lỗi. Trình gỡ rối làm rối loạn nhiều sắc thái/tối ưu tinh tế, vì vậy tôi chỉ có thể đoán đây là một trong những thời điểm mà trình gỡ rối quan trọng. Mà làm cho nó thậm chí còn khó khăn hơn để gỡ lỗi ;-p

+1

Đó chính xác là những gì tôi đã bỏ lỡ. –

+1

Tôi nhận được 'Foo' ở chế độ phát hành, 'Foo'and'Bar' trong Chế độ gỡ lỗi. Từ quan điểm ngôn ngữ lập trình thô, không nên hiển thị cả 'Foo' và 'Bar' theo thứ tự? –

6

Jon's answers page thảo luận về điều này. Tôi không phải là C#, nhưng có vẻ như hệ thống có chính xác một sự lựa chọn khi gọi mã số tĩnh foo (và do đó viết "Foo") nhưng nó có bản chất tự do vô hạn để quyết định khi nào khởi tạo Bar.i (sẽ viết "Bar"), do đó, nó có thể xảy ra hoặc khi lớp được tải, hoặc khi nó được sử dụng lần đầu tiên, hoặc không phải ở tất cả.

0

Chỉ cần nhìn vào nó, tôi sẽ ngạc nhiên nếu nó hiển thị bất cứ điều gì khác nhưng "FooBar".

Vì lý do đơn giản bạn đang truy cập Foo trước, do đó hàm tạo tĩnh sẽ chạy. Tiếp theo là bộ khởi tạo trường tĩnh khi khởi tạo Bar.

Vui lòng được sửa chữa.

4

Nó in Foo, Bar trong chế độ gỡ lỗi và Bar, Foo trong chế độ phát hành. Vì vậy, những gì đang xảy ra là mã phát hành được tối ưu hóa và tối ưu hóa làm Bar được gọi là đầu tiên - nhưng có no đảm bảo rằng sẽ luôn luôn như vậy.

+1

Tại sao thanh nguyên nhân tối ưu hóa được gọi trước tiên. Quy tắc ở đây là gì? –

+0

Tôi sẽ phải kiểm tra, nhưng tôi sẽ không ngạc nhiên nếu nó là trình gỡ lỗi, nhiều hơn là gỡ lỗi/giải phóng, làm rối tung mọi thứ. Nó thường xuyên. –

+2

Vì thanh không có hàm tạo tĩnh nên nó có thể khởi tạo giá trị cho i và lấy lớp Bar sẵn sàng trước thời hạn. Điều này ngăn cản nhiều công việc xảy ra sau này. Ngoài ra, trình gỡ lỗi cho phép Bar nhận được tình trạng khó khăn sau này.Foo, bởi vì nó có hàm khởi tạo, sẽ luôn được khởi tạo khi được tạo lần đầu tiên, trong khi Bar được tự do khởi tạo bất cứ lúc nào. –

0

Tôi nghĩ rằng thanh foo sẽ được in. Phương thức khởi tạo kiểu tĩnh sẽ được thực hiện đầu tiên trong Foo, sau đó phương thức Init sẽ được gọi trên lớp Bar. Tôi không biết liệu hành vi có thể thay đổi hay không. Hay đấy.

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