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

瓦拜·贾恩

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

我知道装箱和拆箱是什么,但我无法理解它的实际用途。为什么在哪里使用?

short s = 25;

object objshort = s;  //Boxing

short anothershort = (short)objshort;  //Unboxing
杰森

为什么

要拥有统一的类型系统并允许值类型具有与引用类型表示其基础数据的方式完全不同的基础数据表示形式(例如,anint只是一个32位的存储桶,与引用完全不同)类型)。

这样想吧。您有一个otype变量object现在您有了一个,int并且想要将其放入oo是对某处某物的引用,而int该书着重不是对某处某物的引用(毕竟,它只是一个数字)。因此,您要执行的操作是:创建一个object可以存储的int对象,然后将对该对象的引用分配给o我们称此过程为“装箱”。

因此,如果您不关心拥有统一的类型系统(即,引用类型和值类型具有非常不同的表示形式,并且您不希望使用通用的方式“表示”这两者),则无需装箱。如果您不关心int表示其基础值(即也int可以是引用类型,而只是存储对其基础值的引用),则无需装箱。

我应该在哪里使用它。

例如,旧的集合类型ArrayList只吃objects。也就是说,它仅存储对居住在某处的事物的引用。没有装箱,您将无法放入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);

在继续下一句话之前,请先考虑一下。

如果你说的TrueFalse伟大!等一下 那是因为==在引用类型上使用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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Java

为什么我们在Java中使用自动装箱和拆箱?

来自分类Dev

为什么拆箱需要在C#中进行显式转换?

来自分类Dev

为什么我们需要在C#中锁定并反对?

来自分类Java

为什么有些语言需要装箱和拆箱?

来自分类Dev

为什么我们需要在Linux上挂载?

来自分类Javascript

为什么我们需要在全局和本地安装gulp?

来自分类Dev

为什么我们需要在两个选择中使用 () 和?

来自分类Dev

为什么我们需要在此脚本中调用“ c.set.bind(c)”?

来自分类Dev

为什么我们需要在C ++头文件中使用“ #if defined Identifier”?

来自分类Dev

C#中的装箱/拆箱

来自分类Dev

装箱和拆箱的C ++类

来自分类Dev

为什么我们需要在终端中以root用户身份进行关机和重新启动?

来自分类Dev

为什么我们需要在Azure数据工厂中执行ML批处理执行和更新资源选项

来自分类Dev

为什么我们需要javadoc和sources jar?

来自分类Dev

为什么我们需要 LiveData 和 ViewModel

来自分类Dev

为什么我们需要Bower和Nuget?

来自分类Dev

为什么我们需要分别编译和链接?

来自分类Dev

为什么整数自动装箱和拆箱对Java中的Arrays.asList不起作用?

来自分类Dev

为什么我们需要在Windows C ++中链接kernel32.dll,user32.dll等?

来自分类Dev

为什么我们需要在 C++20 中的函数概念参数之后使用 auto?

来自分类Dev

为什么在C#方法中我们需要多个`await`语句?

来自分类Dev

什么时候以及为什么我们需要在bash上使用“ wait”命令?

来自分类Java

为什么自动装箱/拆箱在这里失败?

来自分类Dev

为什么我们需要C ++中的虚函数?

来自分类Dev

为什么我们需要声明枚举变量?(C)

来自分类Dev

我们是否还需要在C#代码和存储过程中都应用Sql Transaction?

来自分类Dev

为什么我们需要TRIM的英特尔SSD工具箱?

来自分类Dev

为什么我们需要需求?

来自分类Dev

我们为什么需要`ngDoCheck`

Related 相关文章

  1. 1

    为什么我们在Java中使用自动装箱和拆箱?

  2. 2

    为什么拆箱需要在C#中进行显式转换?

  3. 3

    为什么我们需要在C#中锁定并反对?

  4. 4

    为什么有些语言需要装箱和拆箱?

  5. 5

    为什么我们需要在Linux上挂载?

  6. 6

    为什么我们需要在全局和本地安装gulp?

  7. 7

    为什么我们需要在两个选择中使用 () 和?

  8. 8

    为什么我们需要在此脚本中调用“ c.set.bind(c)”?

  9. 9

    为什么我们需要在C ++头文件中使用“ #if defined Identifier”?

  10. 10

    C#中的装箱/拆箱

  11. 11

    装箱和拆箱的C ++类

  12. 12

    为什么我们需要在终端中以root用户身份进行关机和重新启动?

  13. 13

    为什么我们需要在Azure数据工厂中执行ML批处理执行和更新资源选项

  14. 14

    为什么我们需要javadoc和sources jar?

  15. 15

    为什么我们需要 LiveData 和 ViewModel

  16. 16

    为什么我们需要Bower和Nuget?

  17. 17

    为什么我们需要分别编译和链接?

  18. 18

    为什么整数自动装箱和拆箱对Java中的Arrays.asList不起作用?

  19. 19

    为什么我们需要在Windows C ++中链接kernel32.dll,user32.dll等?

  20. 20

    为什么我们需要在 C++20 中的函数概念参数之后使用 auto?

  21. 21

    为什么在C#方法中我们需要多个`await`语句?

  22. 22

    什么时候以及为什么我们需要在bash上使用“ wait”命令?

  23. 23

    为什么自动装箱/拆箱在这里失败?

  24. 24

    为什么我们需要C ++中的虚函数?

  25. 25

    为什么我们需要声明枚举变量?(C)

  26. 26

    我们是否还需要在C#代码和存储过程中都应用Sql Transaction?

  27. 27

    为什么我们需要TRIM的英特尔SSD工具箱?

  28. 28

    为什么我们需要需求?

  29. 29

    我们为什么需要`ngDoCheck`

热门标签

归档