为什么我们需要在C#中装箱和拆箱?
我知道装箱和拆箱是什么,但我无法理解它的实际用途。为什么在哪里使用?
short s = 25;
object objshort = s; //Boxing
short anothershort = (short)objshort; //Unboxing
为什么
要拥有统一的类型系统并允许值类型具有与引用类型表示其基础数据的方式完全不同的基础数据表示形式(例如,anint
只是一个32位的存储桶,与引用完全不同)类型)。
这样想吧。您有一个o
type变量object
。现在您有了一个,int
并且想要将其放入o
。o
是对某处某物的引用,而int
该书着重不是对某处某物的引用(毕竟,它只是一个数字)。因此,您要执行的操作是:创建一个object
可以存储的新int
对象,然后将对该对象的引用分配给o
。我们称此过程为“装箱”。
因此,如果您不关心拥有统一的类型系统(即,引用类型和值类型具有非常不同的表示形式,并且您不希望使用通用的方式“表示”这两者),则无需装箱。如果您不关心int
表示其基础值(即也int
可以是引用类型,而只是存储对其基础值的引用),则无需装箱。
我应该在哪里使用它。
例如,旧的集合类型ArrayList
只吃object
s。也就是说,它仅存储对居住在某处的事物的引用。没有装箱,您将无法放入int
这样的收藏中。但是使用拳击,您可以。
现在,在泛型时代,您实际上并不需要它,并且通常可以在不考虑问题的情况下轻松进行。但是需要注意一些注意事项:
这是对的:
double e = 2.718281828459045;
int ee = (int)e;
这不是:
double e = 2.718281828459045;
object o = e; // box
int ee = (int)o; // runtime exception
相反,您必须执行以下操作:
double e = 2.718281828459045;
object o = e; // box
int ee = (int)(double)o;
首先,我们必须明确地取消double
((double)o
)的装箱,然后将其转换为int
。
以下结果是什么:
double e = 2.718281828459045;
double d = e;
object o1 = d;
object o2 = e;
Console.WriteLine(d == e);
Console.WriteLine(o1 == o2);
在继续下一句话之前,请先考虑一下。
如果你说的True
和False
伟大!等一下 那是因为==
在引用类型上使用reference-equality来检查引用是否相等,而不是检查基础值是否相等。这是很容易犯的危险。也许更加微妙
double e = 2.718281828459045;
object o1 = e;
object o2 = e;
Console.WriteLine(o1 == o2);
还将打印False
!
最好说:
Console.WriteLine(o1.Equals(o2));
幸运的是,它将打印出来True
。
最后一个微妙之处:
[struct|class] Point {
public int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Point p = new Point(1, 1);
object o = p;
p.x = 2;
Console.WriteLine(((Point)o).x);
输出是什么?这取决于!如果Point
为,struct
则输出为;1
如果Point
为,class
则输出为2
!装箱转换将复制装箱的值,以解释行为上的差异。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句