2016-03-25 22 views
7

tôi stumbled khi điều kỳ lạ này ngày hôm nay:Tại sao bản dịch này không được biên dịch?

http://www.yoda.arachsys.com/csharp/teasers.html

Câu hỏi # 5.

Mã:

using System; 

class Test 
{ 
    enum Foo 
    { 
     Bar, 
     Baz 
    }; 

    const int One = 1; 
    const int Une = 1; 

    static void Main() 
    { 
     Foo f = One - Une; 
     Console.WriteLine(f); 
    } 
} 

Bây giờ theo các câu trả lời trên http://www.yoda.arachsys.com/csharp/teasers-answers.html cho câu hỏi # 5

... Đó là một lỗi được biết do một số tối ưu hóa được thực hiện quá sớm, thu hằng của 0 và nghĩ rằng bất kỳ 0 hằng số đã biết nào phải được chuyển đổi thành giá trị 0 của bất kỳ enum nào. Đó là với chúng tôi bây giờ, và dường như không bao giờ được cố định vì nó có thể phá vỡ một số mã đó là kỹ thuật bất hợp pháp nhưng làm việc hoàn toàn tốt. Có thể là thông số kỹ thuật sẽ thay đổi thay vào đó, tất nhiên.

Nhưng tại sao?

One & Une đều là const. I E. chúng có thể được tính toán thời gian biên dịch, vì vậy nó sẽ trở thành Foo f = 0. Và kể từ 0 là giá trị hợp lệ cho bất kỳ enum, tại sao bản dịch này không được biên dịch?

+0

Bạn đang tìm kiếm một cái gì đó như thế này 'Foo f' và sau đó' f.Bar = One - Une; 'phải không? –

+0

Bởi vì có lẽ kiểm tra "là nó một số nguyên không đổi? Nếu có, là nó 0? Sau đó nó là ok để ngầm đúc nó vào một enum" được thực hiện TRƯỚC KHI tính toán liên tục. – xanatos

+2

Loại an toàn. Ngay cả khi enum của bạn được hỗ trợ bởi một int, enum của bạn là * không * một int. Nó đại diện cho các khái niệm riêng của nó, và như vậy, gán một int cho một enum không phải là cách chính xác để làm việc với nó. –

Trả lời

7

Vấn đề không phải là trình biên dịch có thể hoặc không thể làm cho chương trình này hoạt động. Vấn đề là: Yêu cầu ngôn ngữ nào yêu cầu yêu cầu được thực hiện?

Hành vi này là một dạng sai lệch so với thông số kỹ thuật nên đó là lỗi trình biên dịch.

6.1.3 Implicit liệt kê chuyển đổi Một chuyển đổi liệt kê ngầm cho phép thập phân-nguyên-đen 0 được chuyển đổi sang bất kỳ enum-type và cho bất kỳ nullable loại có loại cơ bản là một enum-type.

Vì vậy, nó phải là một chữ. 1-1 không phải là số không bằng chữ. 0 là số không bằng chữ.

Tôi tự hỏi tại sao thông số nói "thập phân". Điều này có nghĩa là hexadecimal-integer-literal không được bao gồm nên 0x0 cũng không hoạt động.

+0

lý do tại sao nó biên soạn tốt trong năm 2012 và 2015? –

+0

Lỗi trình biên dịch chưa được khắc phục vì lý do tương thích. Nó sẽ phá vỡ mã mà trước đây đã làm việc. – usr

+0

Tôi chỉ biết rằng có một phiên bản trình biên dịch C# lỗi cho phép 'E e = new DateTime()'! Tuy nhiên, điều đó đã được khắc phục: https://blogs.msdn.microsoft.com/ericlippert/2006/03/29/the-root-of-all-evil-part-two/ – usr

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