为什么我们需要在 C# 中装箱和拆箱? [英] Why do we need boxing and unboxing in C#?

查看:42
本文介绍了为什么我们需要在 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只吃objects.也就是说,它只存储对某处某物的引用.如果没有装箱,您就不能将 int 放入这样的集合中.但是通过拳击,你可以.

For example, the old collection type ArrayList only eats objects. 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.

如果你说 TrueFalse 太好了!等等,什么?这是因为引用类型上的 == 使用引用相等来检查引用是否相等,而不是基础值是否相等.这是一个很容易犯的危险错误.也许更微妙

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);

输出是什么?这取决于!如果 Pointstruct 那么输出是 1 但如果 Pointclass> 那么输出是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆