2008-09-04 44 views
19

Tôi đã đoạn mã sau C#:C# số hằng

byte rule = 0; 
... 
rule = rule | 0x80; 

trong đó sản xuất các lỗi:

Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)

[Cập nhật: Phiên bản đầu tiên của câu hỏi đã sai ... tôi không nhận định sản lượng biên dịch ]

Thêm các diễn viên không sửa chữa các vấn đề:

rule = rule | (byte) 0x80; 

tôi cần phải viết nó như:

rule |= 0x80; 

Mà chỉ cần có vẻ lạ. Tại sao toán tử |= khác với toán tử |?

Có cách nào khác để yêu cầu trình biên dịch xử lý hằng số dưới dạng byte không?


@ Giovanni Galbo: có và không. Mã này đang xử lý lập trình của bộ nhớ flash trong một thiết bị bên ngoài và biểu diễn logic một byte bộ nhớ. Tôi có thể bỏ nó sau, nhưng điều này dường như rõ ràng hơn. Tôi đoán di sản C của tôi đang hiển thị quá nhiều!

@ Jonathon Hà Lan: 'là' cú pháp trông gọn gàng nhưng tiếc là không xuất hiện để làm việc ... nó tạo ra:

The as operator must be used with a reference type or nullable type ('byte' is a non-nullable value type)

Trả lời

6
int rule = 0; 
rule |= 0x80; 

http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx | toán tử được định nghĩa cho tất cả các loại giá trị. Tôi nghĩ rằng điều này sẽ tạo ra kết quả mong muốn. Toán tử "| =" là một hoặc sau đó gán toán tử, chỉ đơn giản là viết tắt cho quy tắc = quy tắc | 0x80.

Một trong những điều tuyệt vời hơn về C# là nó cho phép bạn làm những điều điên rồ như loại giá trị lạm dụng chỉ đơn giản dựa trên kích thước của chúng. Một 'int' là chính xác giống như một byte, ngoại trừ trình biên dịch sẽ ném cảnh báo nếu bạn thử và sử dụng chúng như cả hai cùng một lúc. Đơn giản chỉ cần gắn bó với một (trong trường hợp này, int) hoạt động tốt. Nếu bạn quan tâm đến sự sẵn sàng 64bit, bạn có thể chỉ định int32, nhưng tất cả int là int32s, thậm chí chạy ở chế độ x64.

+0

Như bạn nói, tất cả int là int32, không phải là đặc tả ngôn ngữ (hoặc CLR) thực hiện bảo đảm này? – Eloff

+4

int là một bí danh C# cho Int32 và chắc chắn không giống như một byte. Trình biên dịch JIT là nền tảng nhận thức nên chúng ta không cần phải như vậy. Kích thước từ gốc, địa chỉ và hiệu quả của các hoạt động chống lại các nguyên thủy gốc khác nhau có nhiều khả năng được tham gia vào cách phân bổ dữ liệu được quản lý (bao gồm cả "nguyên thủy") trong hệ thống cơ bản.Hãy xem xét rằng cùng một mã có thể được biên dịch cho .NET Micro cũng như .NET CF (nhắm mục tiêu ARM cho điện thoại và PowerPC cho XBox 360). Các hệ thống này thậm chí có thể thể hiện số của chúng với độ tin cậy khác nhau có ảnh hưởng lớn đến hoạt động nhị phân. – TheXenocide

34

C# không có hậu tố theo byte cho byte. u = uint, l = dài, ul = ulong, f = phao, m = thập phân, nhưng không có byte. Bạn phải bỏ nó.

+2

Điều đó xảy ra như thế nào? – User

+2

người dùng: không xác định được thông số kỹ thuật ngôn ngữ C#. Có ví dụ tại đây: http://msdn.microsoft.com/en-us/library/5bdb6693(VS.80).aspx Bạn có thể khai báo và khởi tạo biến byte như ví dụ sau: byte myByte = 255 ; Trong khai báo trước, số nguyên 255 được chuyển đổi hoàn toàn từ int sang byte. Nếu số nguyên nguyên vượt quá phạm vi byte, thì lỗi biên dịch sẽ xuất hiện. – blizpasta

9

Cụm từ bạn đang tìm kiếm là "Literal" và tiếc là C# không có byte byte.

Dưới đây là danh sách all C# literals.

3

Theo số ECMA Specification, pg 72 không có byte theo nghĩa đen. Chỉ các chữ số nguyên cho các loại: int, uint, long và ulong.

0

Thật không may, việc truy đòi duy nhất của bạn là làm theo cách bạn có. Không có hậu tố để đánh dấu chữ là byte. Các | toán tử không cung cấp cho chuyển đổi ngầm định như một phép gán (tức là khởi tạo).

11

này hoạt động:

rule = (byte)(rule | 0x80); 

Rõ ràng khái niệm 'quy tắc | 0x80 'trả về một int ngay cả khi bạn xác định 0x80 là' const byte 0x80 '.

0

Apparently the expression 'rule | 0x80' returns an int even if you define 0x80 as 'const byte 0x80'.

Tôi nghĩ quy tắc là các số như 0x80 mặc định là int trừ khi bạn bao gồm hậu tố theo chữ. Vì vậy, đối với biểu thức rule | 0x80, kết quả sẽ là một int vì 0x80 là một int và quy tắc (là một byte) một cách an toàn có thể được chuyển đổi thành int.

+0

Điều này không đúng. Thậm chí nếu bạn cast 0x80 thành một byte, toán tử '|' cho bạn một int. Thử: 'rule = rule | (byte) 0x80; 'để xem ý tôi là gì. Bạn có thể, tuy nhiên, quấn toàn bộ hoạt động trong ngoặc đơn và đúc tất cả thành byte: 'rule = (byte) (quy tắc | 0x80);' – Ethan

0

Theo tiêu chuẩn C, byte LUÔN thúc đẩy để int trong biểu thức, thậm chí hằng số. Tuy nhiên, miễn là cả hai giá trị được UNSIGNED, các bit có thứ tự cao sẽ bị loại bỏ, do đó hoạt động sẽ trả lại giá trị chính xác.

Tương tự như vậy, nổi thúc đẩy tăng gấp đôi, vv

Kéo ra khỏi bản sao của K & R. Đó là tất cả trong đó.

1

Gần năm năm và không ai thực sự trả lời câu hỏi.

Một vài câu trả lời cho rằng vấn đề là thiếu byte, nhưng điều này không liên quan. Nếu bạn tính toán (byte1 | byte2) kết quả là loại int. Ngay cả khi "b" là hậu tố chữ cho byte, loại (23b | 32b) vẫn sẽ là int.

Liên kết trả lời được chấp nhận cho bài viết MSDN tuyên bố rằng operator| được xác định cho tất cả các loại tích phân, nhưng điều này cũng không đúng.

operator| không được xác định trên byte do đó trình biên dịch sử dụng quy tắc phân giải quá tải thông thường của nó để chọn phiên bản được xác định trên int. Do đó, nếu bạn muốn gán kết quả vào một byte bạn cần phải cast nó:

rule = (byte)(rule | 0x80); 

Vấn đề còn lại, tại sao rule |= 0x80; làm việc?

Do đặc tả C# có quy tắc đặc biệt cho phép gán hợp chất cho phép bạn bỏ qua chuyển đổi rõ ràng. Trong phân bổ hợp chất x op= y quy tắc là:

if the selected operator is a predefined operator, if the return type of the selected operator is explicitly convertible to the type of x, and if y is implicitly convertible to the type of x or the operator is a shift operator, then the operation is evaluated as x = (T)(x op y) , where T is the type of x, except that x is evaluated only once.