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

查看:393
本文介绍了为什么我们需要装箱和拆箱在C#中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我们需要在C#装箱和拆箱?

我知道什么是装箱和拆箱的,但我不能COM prehend真正使用它。为什么我应该在哪里使用它?

 短S = 25;

对象objshort = S; //拳击

短anothershort =(短期)objshort; //拆箱
 

解决方案
  

为什么

有一个统一的类型系统,并允许值类型从方式引用类型重新present有自己的底层数据完全不同的重新presentation它们的底层数据(例如,一个 INT 是32位只是一个水桶比引用类型完全不同)。

你可以把它像这样。你必须键入对象的变量 0 。现在你有一个 INT ,你希望把它变成 0 0 是参考一些地方,而 INT 是强调不提及一些地方(毕竟,这是只是一个数字)。所以,你做的是这样的:你犯了一个新的对象,可存储 INT ,然后您指定一个参考该对象 0 。我们称这个过程为拳。

所以,如果你不关心有一个统一的类型系统(即引用类型和值类型有很大的不同重新presentations,你不希望有一个共同的方式来重新present两人),那么你就不需要拳。如果你不关心有 INT 重present其潜在价值(即,而不是有 INT 是引用类型太多,只是存储的引用,其​​基础值),那么你就不需要拳击。

  

我应该在哪里使用它。

例如,旧的集合类型的ArrayList 只吃对象秒。即,只存储引用住某处出头。无拳,你不能把一个 INT 进入这样一个集合。但与拳击,就可以了。

现在,在仿制药的日子里,你并不真的需要这一点,可以大致沿,而不用考虑这个问题很愉快。但也有一些注意事项需要注意的:

这是正确的:

 双E = 2.718281828459045;
INT EE =(INT)电子;
 

这是不是:

 双E = 2.718281828459045;
对象o = E; // 框
INT EE =(INT)O; //运行时异常
 

相反,你必须这样做:

 双E = 2.718281828459045;
对象o = E; // 框
INT EE =(int)的(双)O;
 

首先,我们必须明确地拆箱(双)O ),然后强制转换到 INT

这是以下的结果:

 双E = 2.718281828459045;
双D = E;
对象01 = D;
对象02 = E;
Console.WriteLine(D = = E);
Console.WriteLine(01 == O2);
 

想想看才去到下一个句子中的第二个。

如果你说太棒了!等等,什么?这是因为 == 的引用类型使用引用相等它检查,如果引用是等价的,如果没有潜在的价值是相等的。这是一个危险的容易犯的错误。也许更微妙

 双E = 2.718281828459045;
对象O1 = E;
对象02 = E;
Console.WriteLine(01 == O2);
 

也将打印

最好说:

  Console.WriteLine(o1.Equals(O2));
 

这也就那么,值得庆幸的是,打印

最后一个细微之处:

  [结构|类]点{
    公众诠释的x,y;

    公共点(INT X,int y)对{
        this.x = X;
        this.y = Y;
    }
}

点p =新点(1,1);
对象o = P;
p.x = 2;
Console.WriteLine(((点)O).X);
 

输出的是什么?这取决于!如果结构则输出为 1 但如果则输出为 2 !装箱转换,使值的副本耳光的解释行为的差异。

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

解决方案

Why

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

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."

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.

where should I use it.

For example, the old collection type ArrayList only eats objects. That is, it only stores references to somethings that live somewhere. Without boxing you can not 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:

This is correct:

double e = 2.718281828459045;
int ee = (int)e;

This is not:

double e = 2.718281828459045;
object o = e; // box
int ee = (int)o; // runtime exception

Instead you must do this:

double e = 2.718281828459045;
object o = e; // box
int ee = (int)(double)o;

First we have to explicitly unbox the double ((double)o) and then cast that to an int.

What is the result of the following:

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.

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

will also print False!

Better to say:

Console.WriteLine(o1.Equals(o2));

which will then, thankfully, print True.

One last subtlety:

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

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天全站免登陆