我们如何在.NET中为对象分配整数?
引用类型派生自System.Object,值类型来自System.ValueType。
那么,怎么可能呢?
答案 0 :(得分:18)
术语“装箱”非常不透明,但通过使用调试器可以很容易地看到实际发生的情况。写一个像这样的小控制台模式应用程序:
using System;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
int value = 42;
object obj = value;
} // <== Breakpoint here
}
}
在指示的位置设置断点并按F5。当断点命中时,使用Debug + Windows + Memory + Memory 1.在地址框中,键入“obj”。您将获得对象的内存内容的十六进制转储。右键单击窗口并选择“4字节整数”,这是在这种情况下可视化对象的最佳方法。你会看到类似的东西:
0x01CBF6BC 6e1a2d34 0000002a
这里有趣的部分是0x01CBF6BC,这是垃圾收集堆上对象的地址。下一个十六进制数6e1a2d34是所谓的“类型句柄”,也称为“方法表指针”。这是一个标识对象类型的“cookie”。在这种情况下,System.Int32。非常重要的是,稍后将对象取消装箱回Int32以验证盒装值实际上是整数时使用它。
您看到的下一个值0000002a是盒装对象的值。你可以在程序员模式下使用Windows计算器转换回十进制,它是42。
试验一下,使用不同的值和不同的类型来查看它如何影响盒装对象。您可以修改十六进制,看看它对调试器显示的obj值有什么影响。
我给你的十六进制转储是一个4字节的盒装值,装箱一个double需要8个字节。装箱结构将需要更多的字节。还有一个你看不到的对象标题的一部分,即所谓的syncblock,位于地址 - 4.尝试使用lock语句来查看更改。
答案 1 :(得分:13)
这是由boxing
和unboxing
的流程完成的。请参阅以下链接以获取进一步参考:
Boxing and Unboxing (C# Programming Guide)
Boxing and Unboxing of Value Types : What You Need to Know?
What is the difference between boxing/unboxing and type casting?
答案 2 :(得分:7)
Boxing是将值类型转换为类型对象或由此值类型实现的任何接口类型的过程。当CLR选中一个值类型时,它将值包装在System.Object中并将其存储在托管堆上。取消装箱从对象中提取值类型。
答案 3 :(得分:5)
你是boxing对象中的整数。
也就是说,创建一个包装(或 box )整数的对象。有点像在现实生活中把东西放在盒子里。
答案 4 :(得分:4)
试试这个方法:
object ob;
int i=10;
ob=i;//(boxing)
int b;
b=(int)ob;//(unboxing)
答案 5 :(得分:3)
如果你看System.ValueType
,它也来自System.Object
另见How do ValueTypes derive from Object (ReferenceType) and still be ValueTypes
答案 6 :(得分:3)
你应该在c#中阅读boxing and unboxing,它应该告诉你如何/为什么。
此链接有一个很好的解释,并解释了您询问的参考和值类型问题:
http://www.dijksterhuis.org/exploring-boxing/
Boxing就像在包装器中简单地放置一个基本类型(使其成为一个完全被吹制的对象),并取消装箱包装对象并将其转换回更简单的类型。要执行装箱托管内存需要在堆上分配,需要更新引用,并且必须复制值类型的内容。
答案 7 :(得分:1)
.NET中的int有一个底层的Integer类型对象和一个隐式转换。
答案 8 :(得分:0)
System.ValueType也是从System.Object派生的,所以这就是原因:
请参阅此处的继承层次结构:
http://msdn.microsoft.com/en-us/library/system.valuetype.aspx