static void Main(string[] args)
{
int i = 2;
i.GetType();
//装箱,因为i为值类型,而GetType方法调用的是系统的方法,调用系统的GetType方法需要一个object对象,所以装箱
object o = i;
//装箱,将值类型转化为object
ArrayList al = new ArrayList();
al.Add(i);
//装箱,将值类型转化为object,因为Arraylist的Add方法的参数类型是object
Hashtable ht = new Hashtable();
ht.Add(3, i);
//2次装箱,将值类型转化为object,因为Hashtable的Add方法的2个参数类型都是object
Console.WriteLine(i + "," + (int)o);
//2次装箱,i转化为String类型(即引用型),int(o)也装箱从int型转为String型
Console.ReadKey();
}
今天学了box 和unbox . 个人理解:
1.
装箱
box
,就是将值类型转化为引用类型
2.拆箱
unbox
,就是将引用类型转化为值类型
box和unbox是一个非常耗费内存的操作,应尽量避免--怎么避免还不太清楚。
不过选择值类型还是引用类型,今天学到了一点:
1.根据数据大小,数据小的存值类型,改善系统性能
2.没有继承,没有多态的,没有表现出行为的,用值类型
3.由于值类型传值的时候传的是实例数据,而不是内存地址,有高效的内存支持,且不在暴露内部结构的情况下返回实例数据的副本。从安全性上有有优势,但过多的值传递会影响性能
4.要box和unbox的,用引用类型
系统自带的ToString方法也是一种装箱的操作,因为是System.Type类下的方法,当然,如果自己重写了ToString()方法不涉及对象的话,那就没有装箱了。
按照我自己的理解再做一遍解释,权充学习了。
Struct A : ICloneable
{
public Int32 x;
public override String ToString() {
return String.Format("{0}",x);
}
public object Clone() {
return MemberwiseClone();
}
}
static void main()
{
A a;
a.x = 100;
Console.WriteLine(a.ToString());
Console.WriteLine(a.GetType());
A a2 = (A)a.Clone();
ICloneable c = a2;
Ojbect o = c.Clone();
}
ps:struct和decimal在c#中是值类型。
a.ToString():调用的不是系统自带的ToString,方法内不涉及装箱,所以不装箱
a.GetType():调用的是System.ValueType类的GetType方法,所以涉及装箱
a.Clone():我看不出为什么不用装箱,头有点晕。
a.GetType():调用的是System.ValueType类的GetType方法,所以涉及装箱
a.Clone():我看不出为什么不用装箱,头有点晕。
MemberwiseClone(),浅表复制,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。 如果字段是值类型的,则对该字段执行逐位复制。 如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
<//www.w3.org/1999/xhtml:sentencetext xmlns="http://www.w3.org/1999/xhtml">貌似是创建了一个新对象,而不是隐式转换。回头再看看,利用ILDASM.exe说不定能解开疑惑。
ICloneable c转型:装箱,a2是一个值类型,转化为ICloneable要装箱。
c.Clone()。c是一个引用类型,可以调用父类object的方法,这里有继承,但没有装箱。
ICloneable c转型:装箱,a2是一个值类型,转化为ICloneable要装箱。
c.Clone()。c是一个引用类型,可以调用父类object的方法,这里有继承,但没有装箱。
--------------------------暂时就这么多,我习惯通过做题来学习巩固知识---------------------------------------