C#中的变量分为值类型和引用类型两种。值类型变量存储在栈上,比较简单;引用型变量存储在堆上,比较复杂。
int n = 123;
Object obj = n; //装箱
string s = obj.ToString();
这里 C#在暗中进行了魔术转换——装箱(Boxing)。装箱操作能把值类型数据打包到引用型变量中,使我们能够像使用对象一样使用值类型变量。 系统先创建引用型变量obj,在堆中为 obj 分配空间,并存入 n 的值,这样 n 就被装入引用型数据obj 中了。
对于装入箱中的数据,可以通过拆箱(Unboxing)操作释放出来,拆箱操作要用显式 转换。
int i = (int)obj; //拆箱
咋一看很不理解C#这个东西为什么值得拿出来说,上面的装箱代码可以写成
//C#
int n = 123;
int[] m = new int[1];
m[0] = n;//这样是不是也可以理解为是装箱
string s = m[0].ToString();
//C++
int n = 123;
int* m = new int[1];
m[0] = n;//这样是不是也可以理解为是装箱
//...
delete[] m;
拆箱代码
//C#
int i = m[0];
//C++
int i = m[0];
这不就是个给堆上分配空间赋值的过程吗?obj的引用不就相当于指针吗?这到底有啥好单独拿出来讲的?
but,当一个方法的参数类型不能确定时,装箱操作就非常有用。假设我们有一个仓库Storehouse,用 来存储各种各样的物品
public Object[] items;
private int count;
//方法:向仓库里添加货物
public void Add(object obj)
{
if (count < items.Length)
{
items[count] = obj; count++;
}
else
{
Console.WriteLine("仓库已满.");
}
}
Storehouse store = new Storehouse(5);
//向仓库里添加货物
store.Add(100);
store.Add(3.14);
store.Add("Good");
store.Add(new Bird());
store.Add(new Cat());
简直屌炸有没有。比C++泛型编程的实现可简单多了;