Tôi đã thử nghiệm điều này, sử dụng ILSpy để kiểm tra đầu ra và đây là những gì tôi đã khám phá.
Rõ ràng trong trường hợp thứ hai của bạn đây là lỗi - bạn không thể so sánh ulong
và int
vì không có loại nào bạn có thể ép buộc cả hai. A ulong
có thể quá lớn đối với số long
và int
có thể âm.
Trong trường hợp đầu tiên, trình biên dịch đang được thông minh. Nó nhận ra rằng const 1
> const 32
là không bao giờ đúng, và không bao gồm tuyên bố if
của bạn trong đầu ra biên dịch cả. (Nó sẽ đưa ra một cảnh báo cho mã không thể truy cập.) Nó giống nhau nếu bạn xác định và sử dụng một số const int
thay vì chữ, hoặc thậm chí nếu bạn đúc một cách rõ ràng (nghĩa là (int)32
).
Nhưng sau đó không phải là trình biên dịch so sánh thành công số ulong
với số int
mà chúng tôi vừa nói là không thể?
Dường như không. Vì vậy, những gì là đang diễn ra?
Hãy thử thay vì làm điều gì đó dọc theo các dòng sau. (Lấy đầu vào và đầu ra bằng văn bản để trình biên dịch không biên dịch bất cứ điều gì đi.)
const int thirtytwo = 32;
static void Main(string[] args)
{
ulong x = ulong.Parse(Console.ReadLine());
bool gt = x > thirtytwo;
Console.WriteLine(gt);
}
này sẽ biên dịch, mặc dù ulong
là một biến, và mặc dù kết quả là không biết đến lúc biên dịch. Hãy nhìn vào sản lượng trong ILSpy:
private static void Main(string[] args)
{
ulong x = ulong.Parse(Console.ReadLine());
bool gt = x > 32uL; /* Oh look, a ulong. */
Console.WriteLine(gt);
}
Vì vậy, trình biên dịch là trong thực tế điều trị của bạn const int
như một ulong
. Nếu bạn thực hiện thirtytwo = -1
, mã không thể biên dịch được, mặc dù sau đó chúng tôi biết rằng gt
sẽ luôn là là đúng. Bản thân trình biên dịch không thể so sánh một số ulong
với một số int
.
Cũng lưu ý rằng nếu bạn thực hiện x
một long
thay vì một ulong
, trình biên dịch tạo ra 32L
hơn 32
là một số nguyên, mặc dù nó không có tới. (Bạn có thể so sánh một int
và long
khi chạy.)
điểm này để trình biên dịch không điều trị 32
như một ulong
trong trường hợp đầu tiên bởi vì nó có đến, chỉ vì nó thể phù hợp với loại x
. Nó tiết kiệm thời gian chạy từ việc phải ép buộc hằng số, và đây chỉ là tiền thưởng khi cưỡng chế nên bởi các quyền không thể thực hiện được.
Lý do cho lỗi này là rõ ràng. Trong ví dụ thứ hai bạn đang cố gắng thực hiện một hoạt động bất hợp pháp với một số nguyên. Trong ví dụ đầu tiên, '32' đang được coi là' ulong'. Bạn thực sự nên tạo 'mask' là' ulong'. –
@Ramhound Hoặc là (làm 'so sánh' một 'ulong'), hoặc tạo' so sánh' một biến 'const', vì vậy' const int compare = 32; '. Các biểu thức liên tục sẽ chuyển đổi tự động một cách hạnh phúc từ 'int' thành' ulong' tại thời gian biên dịch nếu chúng không âm, một cái gì đó nằm dưới tên _Implicit constant expression conversion_. –