2010-10-13 14 views
9

Ok Tôi phải xem cái gì đó cực kỳ đơn giản nhưng tôi bị mất.Bối rối bằng Quyền anh. Đúc 1 đến Int64 ném InvalidCastException

Với này

object val = -1; 
var foo = (Int32)(val); 
var bar = (Int64)(val); 

Dàn diễn viên để Int64 ném và InvalidCastException.

Tôi nhận ra điều này liên quan đến một số sự kỳ lạ với quyền anh nhưng tôi không hiểu lý do.

Từ những gì tôi hiểu val được đóng hộp là Int32 trên dòng đầu tiên.

Sau đó, khi tôi cố gắng truyền dưới dạng gì đó khác với Int32 InvalidCastException được ném. Tôi cho rằng điều này có nghĩa rằng tôi đang cố gắng unbox val như Int64 khi nó thực sự là một Int32?

Vẫn có vẻ lạ. Không thể bỏ chọn hộp giá trị và sau đó thử thực hiện dàn diễn viên?

Giống như (Rõ ràng đây là khủng khiếp đơn giản đi, có lẽ loại đóng hộp không biết vì vậy đây là không thể?):

object val = -1; 
Int32 unboxed = (Int32)(val); 
var bar = (Int64)(unboxed); 

người (đọc: Eric Lippert) Trường tôi trên lý do đằng sau điều này.

UPDATE: Từ Blog của Eric rằng Reed gửi một liên kết đến đây là câu trả lời ngắn gọn tôi đang tìm kiếm

" ... Đây sẽ là một số tiền rất lớn của mã để tạo ra, và nó sẽ là Tất nhiên, mã này rất lớn và bạn muốn đặt nó theo phương pháp riêng của nó và chỉ tạo ra một cuộc gọi cho nó, thay vì làm điều đó theo mặc định, và luôn tạo ra mã chậm, lớn và mong manh, thay vào đó, thay vào đó, Nếu bạn muốn gọi phương thức chậm làm tất cả điều đó, nó có sẵn - bạn luôn có thể gọi Convert.ToInt32, thực hiện tất cả những phân tích đó khi chạy cho bạn. Chúng tôi cung cấp cho bạn sự lựa chọn giữa "nhanh và chính xác" hoặc "chậm và lỏng lẻo", và mặc định hợp lý là trước đây. Nếu bạn muốn sau đó gọi phương thức .... "

+0

Đây là một cái gì đó. vô cùng phi sim ple. Nó đi lên rất nhiều người ... –

+0

Reed là đúng; điều này được hỏi vài lần một tuần về SO. Nó được hỏi hai lần hôm qua. –

+0

Vì vậy, tôi rõ ràng lame vì hỏi cùng một câu hỏi mà mọi người khác hỏi và không tìm kiếm trước. Tôi thấy điều thú vị là điều này vẫn nhận được 6 phiếu bầu nếu đó là một câu hỏi phổ biến. Rõ ràng hành vi mặc định không phải là hành vi hiển nhiên nhất. –

Trả lời

15

Điều này là do bạn không thể bỏ hộp thư và thực hiện chuyển đổi trong một thao tác đơn lẻ. Bạn phải hủy gắn giá trị Int32 thành Int32, và sau đó chuyển đổi . loại của nó

Do đó, điều này đòi hỏi các đối tượng được mở hộp, sau đó chuyển đổi sang Int64:

object val = -1; 
int foo = (Int32)val; 
Int64 bar = (Int64)(Int32)val; 

Eric Lippert được bảo hiểm này một cách chi tiết về bài đăng blog của mình với tựa đề Representation and Identity

+0

Tuyệt vời, Eric Lippert bởi proxy :) Bạn đá –

+0

Một cách khác để viết: 'Int64 a = -1; đối tượng o = a; Int64 b = (Int64) o; 'Cảm ơn Reed! – Nayan

+0

Mọi người có thể ngừng nói * bỏ * khi họ muốn nói * chuyển đổi * không? Không có "đúc" giữa các loại số nguyên; chúng đang được * chuyển đổi *.(Thật không may là C# sử dụng cùng một cú pháp cho cả hai.) – Timwi

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