2010-08-10 15 views
8

Tôi có đoạn mã sau:boxing và unboxing, tại sao không phải là kết quả đầu ra cả hai "System.Object"?

object var3 = 3; 
Console.WriteLine(var3.GetType().ToString()); 
Console.WriteLine(typeof(object).ToString()); 

Đầu ra là:

System.Int32 
System.Object 

Tại sao không phải cả hai đều System.Object?

+0

@Also OP, cả hai Console.WriteLines sẽ hoạt động, ngay cả khi không có ToString() rõ ràng - nó sẽ được ngầm gọi nếu đối số của bạn loại là một đối tượng. – Gishu

+0

đã xóa bỏ lời chào: "Cảm ơn trước"., Cũng đã xóa các từ bất hợp pháp khỏi tiêu đề: "Câu hỏi về", không làm điều đó vào lần sau –

Trả lời

4

Nếu bạn hỏi tại sao boxedObject.GetType() không trả về Đối tượng .. hãy xem hình ảnh trong phần 'Chuyển đổi quyền anh' trên MSDN Boxing and Unboxing page. Câu hỏi hay về btw .. ít nhất là sự hiểu biết của tôi về câu hỏi của bạn.

Mặc dù tôi có thể không chính xác về mặt kỹ thuật, có vẻ như

  • Khi chuyển đến đống, một đối tượng mới được tạo ra - con trỏ Type của nó thiết lập để các loại giá trị của gốc Loại đối tượng (ở đây hệ thống. Int32). Điều này giải thích GetType() (và cũng là lỗi nếu bạn cố gắng unbox nó sang một loại khác).
  • Giá trị thực tế sau đó được sao chép vào đối tượng này.
7

Hàm GetType() trả về loại thực tế của cá thể trong biến.

Mặc dù biến của bạn được khai báo là object, nó thực sự là giữ một phiên bản đóng hộp Int32.

+0

Tôi không biết các câu trả lời khác đang cố gắng chứng minh điều gì :) – leppie

+1

là tại sao GetType của hộp (đối tượng) trả về Int32 (loại giá trị đóng hộp) thay vì Object - vì boxing làm cho nó tạo ra một đối tượng trên heap. Nếu bạn không nhận được +1 – Gishu

+0

@leppie: Chắc chắn có rất nhiều người trong số họ, không có ở đó :) –

3

Bỏ qua chủ đề quyền anh, tất cả các lớp được kế thừa từ đối tượng loại. Điều này đúng cho cả loại tham chiếu và loại giá trị. GetType hiển thị loại có nguồn gốc nhiều nhất, trong trường hợp này là System.Int32.

Một trong số ít những lần GetType sẽ trở System.Object là nếu bạn làm điều này:

object var = new Object(); 
Console.WriteLine(var.GetType().ToString()); 

Boxing đề cập đến khi một loại giá trị được trỏ đến bởi một loại tài liệu tham khảo. Nói chung điều này được thực hiện như một tham chiếu System.Object. TypeOf sẽ trả về kiểu thực tế có nguồn gốc nhiều nhất, không phải kiểu tham chiếu.

class A 
{ 
} 

class B : A 
{ 
} 

class C : B 
{ 
} 

object obj1 = new ClassA(); 
ClassB obj2 = new ClassB(); 
ClassB obj3 = new ClassC(); 

GetType sẽ làm những việc tương tự cho những loại này.

System.Console.WriteLine(obj1.GetType().ToString()); 
System.Console.WriteLine(obj2.GetType().ToString()); 
System.Console.WriteLine(obj3.GetType().ToString()); 

ClassA
ClassB
ClassC

+0

Loại giá trị không thực sự lấy được từ Object. Chúng hoàn toàn nằm ngoài hệ thống phân cấp loại. Tuy nhiên, đối với mọi loại giá trị, có một loại lớp xuất phát từ ValueType trớ trêu thay (mặc dù tên của nó, đó là một loại lớp). Hệ thống xác định các toán tử chuyển đổi hai chiều tiềm ẩn giữa mỗi loại giá trị và loại lớp được tạo tự động tương ứng của nó. Chuyển đổi ngầm từ kiểu giá trị sang kiểu lớp được gọi là "boxing"; chuyển đổi ngược lại là "unboxing". – supercat

+0

@supercat: Vui lòng chỉnh sửa câu trả lời nếu bạn muốn :) –

1

Đây không phải là thực sự về đấm bốc; đây là về hành vi của GetType. Nó trả về kiểu của giá trị của biến, không phải là loại biến là tuyên bố với:

object var4 = new List<string>(); 
    Console.WriteLine(var4.GetType().ToString()); 

sẽ không trở lại System.Object một trong hai.

+0

Nó sẽ trả về loại cá thể, chứ không phải kiểu tham chiếu –

1

tuyên bố biến là biên dịch thông tin chỉ thời gian trong khi thực thi phương pháp là thời gian chạy.Nói cách khác, không có cách nào GetType() có thể biết loại đối tượng nào được khai báo vì nó chỉ có thể biết loại thực tế của đối tượng trong thời gian chạy.

tương tự nếu bạn có

class a 
{ 
} 

class b : a 

a bInstance = new b(); 
bInstance.GetType(); 

cuộc gọi đến bInstance.GetType() không có cách nào để biết rằng biến được khai báo là kiểu 'a' và tôi không nghĩ rằng bạn mong đợi nó để trở về ' trong trường hợp này. Tuy nhiên trong ví dụ trên a là viết tắt của đối tượng và b là cho System.Int32