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

RJN*_*RJN 19 c# unboxing casting

Boxing是将值类型转换为托管堆对象的过程,这是隐式的.拆箱是反向过程,编译器需要显式转换.由于拳击存储数据类型,为什么不能拆箱使用它而不是要求显式转换?

class BoxUnBox
{
 static void Main()
 {
   int i = 123;      // a value type
   object o = i;     // boxing
   int j = (int)o;   // unboxing - Why is an explicit cast required?
 }
}
Run Code Online (Sandbox Code Playgroud)

Ser*_*kiy 42

您的问题仅与拆箱操作无关.实际上它应该听起来"我为什么要使用显式转换?" 考虑以下示例:

int i = 123;
long l = i;
int j = (int)l; // OMG why??
Run Code Online (Sandbox Code Playgroud)

答案很简单,您可以在C#规范6.2中找到它.显式转换:

显式转换是指无法证明总是成功的转化,已知可能丢失信息的转化,以及跨类型域的转换,这些转换的类型应完全不同,值得使用明确的表示法.

在上面的示例中,您可能会丢失信息,因为long可以保存不适合int范围的值.但是在分配intlong以下内容时,您永远不会丢失信息:

long l = i; // safe
Run Code Online (Sandbox Code Playgroud)

在您的示例中,您需要显式转换,因为无法证明隐式转换始终成功.object类型的变量可以在字面上引用任何类型.串怎么样?

object o = i;  // implicit and always safe
o = "Now I have a machinegun ho-ho-ho"; // safe too
int j = o;     // will not succeed if o is string
Run Code Online (Sandbox Code Playgroud)

比喻

对象变量就像一个黑盒子,你可以放任何东西 - 音乐CD,笔,电话或香蕉.不仅是你,而且任何人都可以在那里放东西.如果你早上放在黑匣子里的最后一件东西是香蕉,你能否在晚上回来吃掉从黑匣子里拿出来的东西?如果你独自生活,房间关闭,你的记忆非常好,那么......你可以.你会想知道为什么每个人在吃之前检查他们的盒子的内容.但是,如果你不是独自生活,或房间没有关闭,或者你只能忘记一次,你把手机放入盒子里......好胃口


Him*_*ere 6

如果有人更改的内容o"Hello World".为了确保您知道自己在做什么,编译器要求您明确地转换盒装值.

基本上,隐式转换意味着任何o类型为object的实例也可以表示为实例,int但实际上并非如此.考虑例如:

int i = -1;
long j = i;
Run Code Online (Sandbox Code Playgroud)

很明显,您的变量i(整数)也可以被视为long.这就是隐式铸造在这里准确的原因.另一方面,并​​非每一个long都可以转换为int 没有任何数据丢失.因此,您需要一个显式的强制转换来确定:我知道可能会有一些数据丢失,但我并不关心它.


A. *_*esa 5

因为一个Int32 一个Object,但Object 可能是一个Int32.编译器知道在第一种情况下要做什么,但是你必须告诉编译器你知道你在第二种情况下做了什么,并保证可以执行拆箱.

继承关系是方向性的!父母与孩子不同.

  • 这是C#,而不是Java.EverythingTHING继承自object,甚至是原始类型.请参见http://stackoverflow.com/a/33247833/1395758. (5认同)
  • @ A.Chiesa这是对与错......为什么技术上一切都从对象继承,对于值类型,继承是"奇怪的" (2认同)