2009-12-23 28 views
8

Trong C#, các phương pháp sau đây sẽ không biên dịch:Tại sao trình biên dịch hoạt động khác với mã này?

public bool IsItTrue() 
{ 
} 

Các lỗi biên dịch: 'IsItTrue()': không phải tất cả đường dẫn mã trả về một giá trị, có ý nghĩa hoàn hảo. Nhưng sau đây biên dịch mà không có bất kỳ vấn đề.

public bool IsItTrue() 
{ 
    while (true) 
    { 
    } 
} 

Có vẻ như không có báo cáo trả lại nào cả. Tại sao nó như vậy? Bất kỳ trợ giúp nào tại đây ...,

Trả lời

13

Trình biên dịch biết rằng phương thức thứ hai sẽ không bao giờ trở lại.

Nếu một trong hai phương pháp bao giờ trở lại trong bất kỳ trường hợp nào thì họ phải trả lại bool.

Phương pháp đầu tiên không chứa bất kỳ vòng lặp vô hạn nào, không ném bất kỳ ngoại lệ vô điều kiện nào, v.v., do đó, nó phải trả lại bool. Mã không trả lại một bool do đó trình biên dịch từ chối biên dịch nó.

Phương pháp thứ hai không bao giờ trả về do vòng lặp vô hạn while (true). Nếu nó không bao giờ trả về sau đó nó không quan trọng gì (nếu có) là không bao giờ trả về để trình biên dịch sẽ cho phép nó biên dịch. hơn

Một vài ví dụ mà các trình biên dịch sẽ nhận ra và cho phép:

public bool IsItTrue() 
{ 
    throw new Exception("Always thrown!"); 
} 

public bool HowAboutThisOne() 
{ 
    if ((46 - 3) < (27 * 9)) 
    { 
     throw new Exception("Always thrown!"); 
    } 
} 
+0

Giải thích nhỏ xin vui lòng .., – Dhana

+0

Thú vị là trình biên dịch sẽ cho phép điều đó.Tôi có thể thấy lý do tại sao nó * có thể được cho phép, nhưng tôi tự hỏi mục đích thực tế của cuộc sống là gì. –

+0

Tôi biết rằng chúng tôi có thể muốn một cái gì đó tương tự như một thời gian (đúng) cho một sợi, nhưng ngay cả một sợi nên kết thúc tại một số điểm? Vì vậy, nếu trình biên dịch có thể phát hiện tình huống như vậy tại sao nó không ném một điểm lỗi một vòng lặp vô hạn? – uriDium

3

Đầu tiên được giải thích độc đáo bởi thông điệp biên dịch lỗi.

Thứ hai không bao giờ trả lại, vì vậy, có không bao giờ bất kỳ giá trị nào được trả lại.

Nó không giống nhau. Trong ví dụ đầu tiên của bạn, phương thức có thể trả về mà không trả lại bất kỳ giá trị nào cho người gọi -> Lỗi trình biên dịch.

Thứ hai sẽ không bao giờ trở lại (trình biên dịch đủ thông minh cho điều đó, nó chỉ ra rằng bạn đã tạo một vòng lặp vô hạn). Nó sẽ không bao giờ nhập vào "Được rồi, tôi đạt đến cuối của phương pháp và không biết những gì để trở về" nhà nước.

1

Halting Problem tuyên bố rằng bạn thường không thể xác định xem chương trình sẽ chấm dứt hoặc chạy mãi mãi. Cho rằng có những ví dụ trong chủ đề này dường như vi phạm nguyên tắc này, tôi nghi ngờ rằng trình biên dịch C# đang thực hiện phân tích về các điều kiện vòng lặp có thể được giảm xuống còn hằng số biên dịch thời gian. Nếu hằng số đánh giá là true, thì chúng ta biết rằng vòng lặp sẽ không bao giờ chấm dứt.

Ví dụ: hãy xem xét hai hàm sau đây.

public bool NoError() 
{ 
    while (true) { } 
} 

public bool Error() 
{ 
    while (NoError()) { } 
} 

Như đã trình bày, chức năng đầu tiên sẽ không tạo ra lỗi thời gian biên dịch. Tuy nhiên, thứ hai sẽ kể từ khi trình biên dịch không thể đánh giá kết quả của hàm gọi NoError(). Đây cũng là trường hợp nếu NoError() được sửa đổi để luôn trả lại true.

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