为什么我们需要在 C# 中装箱和拆箱? [英] Why do we need boxing and unboxing in C#?
问题描述
为什么我们需要在 C# 中装箱和拆箱?
Why do we need boxing and unboxing in C#?
我知道装箱和拆箱是什么,但我无法理解它的真正用途.为什么以及我应该在哪里使用它?
I know what boxing and unboxing is, but I can't comprehend the real use of it. Why and where should I use it?
short s = 25;
object objshort = s; //Boxing
short anothershort = (short)objshort; //Unboxing
推荐答案
为什么
拥有统一的类型系统,并允许值类型对其底层数据的表示与引用类型表示其底层数据的方式完全不同(例如,int
只是一桶32 位,与引用类型完全不同).
To have a unified type system and allow value types to have a completely different representation of their underlying data from the way that reference types represent their underlying data (e.g., an int
is just a bucket of thirty-two bits which is completely different than a reference type).
这样想.您有一个 object
类型的变量 o
.现在你有一个 int
并且你想把它放到 o
中.o
是对某处某物的引用,而 int
显然不是对某某某物的引用(毕竟,它只是一个数字).所以,你要做的是:你创建一个新的 object
来存储 int
然后你将对该对象的引用分配给 o
.我们称这个过程为拳击".
Think of it like this. You have a variable o
of type object
. And now you have an int
and you want to put it into o
. o
is a reference to something somewhere, and the int
is emphatically not a reference to something somewhere (after all, it's just a number). So, what you do is this: you make a new object
that can store the int
and then you assign a reference to that object to o
. We call this process "boxing."
因此,如果您不关心拥有统一的类型系统(即,引用类型和值类型具有非常不同的表示形式,并且您不想要一种通用的方式来表示"两者),那么您就不需要需要拳击.如果您不关心让 int
表示它们的基础值(即,让 int
也成为引用类型,并且只存储对它们的基础值的引用),那么您不需要不需要拳击.
So, if you don't care about having a unified type system (i.e., reference types and value types have very different representations and you don't want a common way to "represent" the two) then you don't need boxing. If you don't care about having int
represent their underlying value (i.e., instead have int
be reference types too and just store a reference to their underlying value) then you don't need boxing.
我应该在哪里使用它.
比如旧的集合类型ArrayList
只吃object
s.也就是说,它只存储对某处某物的引用.如果没有装箱,您就不能将 int
放入这样的集合中.但是通过拳击,你可以.
For example, the old collection type ArrayList
only eats object
s. That is, it only stores references to somethings that live somewhere. Without boxing you cannot put an int
into such a collection. But with boxing, you can.
现在,在泛型时代,您并不真正需要它,并且通常可以在不考虑问题的情况下愉快地进行.但有一些注意事项需要注意:
Now, in the days of generics you don't really need this and can generally go merrily along without thinking about the issue. But there are a few caveats to be aware of:
这是正确的:
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
.
First we have to explicitly unbox the double
((double)o
) and then cast that to an int
.
下面的结果是什么:
double e = 2.718281828459045;
double d = e;
object o1 = d;
object o2 = e;
Console.WriteLine(d == e);
Console.WriteLine(o1 == o2);
在继续下一句之前先考虑一下.
Think about it for a second before going on to the next sentence.
如果你说 True
和 False
太好了!等等,什么?这是因为引用类型上的 ==
使用引用相等来检查引用是否相等,而不是基础值是否相等.这是一个很容易犯的危险错误.也许更微妙
If you said True
and False
great! Wait, what? That's because ==
on reference types uses reference-equality which checks if the references are equal, not if the underlying values are equal. This is a dangerously easy mistake to make. Perhaps even more subtle
double e = 2.718281828459045;
object o1 = e;
object o2 = e;
Console.WriteLine(o1 == o2);
也会打印False
!
最好说:
Console.WriteLine(o1.Equals(o2));
幸运的是,它会打印 True
.
which will then, thankfully, print 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
!装箱转换会复制被装箱的值,解释行为上的差异.
What is the output? It depends! If Point
is a struct
then the output is 1
but if Point
is a class
then the output is 2
! A boxing conversion makes a copy of the value being boxed explaining the difference in behavior.
这篇关于为什么我们需要在 C# 中装箱和拆箱?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!