int和string中的装箱和拆箱

时间:2011-06-21 09:56:47

标签: c# .net types boxing

我在拳击和拆箱方面有点困惑。根据其定义

  

拳击是将ValueTypes隐式转换为引用类型(Object)   UnBoxing是将引用类型(Object)显式转换为其等效的ValueTypes。

描述这个的最好例子是

int i = 123; object o = i;  // boxing

o = 123; i = (int)o;  // unboxing 

但我的问题是int是否是值类型而字符串是引用类型所以

int i = 123; string s = i.ToString();

s = "123"; i = (int)s; 

这是拳击和拆箱的一个例子吗?

4 个答案:

答案 0 :(得分:20)

调用ToString不是拳击。它创建了一个恰好包含int的文本表示的新字符串。

调用(object)1时,会在堆上创建一个包含int的新实例。但它仍然是int。 (您可以使用o.GetType()

进行验证

无法使用强制转换为int转换字符串。所以你的代码不会编译。

如果你首先将你的字符串转换为object,你的代码将被编译但在运行时失败,因为你的对象没有盒装int。您只能将值类型拆分为完全正确的类型(或关联的可为空)。

两个例子:

断裂:

object o=i.ToString();// o is a string
int i2=(int)o;//Exception, since o is no int

工作:

object o=i;// o is a boxed int
int i2=(int)o;//works 

答案 1 :(得分:2)

 int i = 2;
 string s = i.ToString();

这是 NOT 拳击。这只是对Int32.ToString()的方法调用,它返回一个表示int值的格式化字符串。

 i = (int)s;

此代码无法编译,因为System.StringSystem.Int32之间未定义显式转换。

通过以下方式考虑它,以了解什么是拳击取消装箱

  1. 拳击:当你获取一个值类型并将其“粘贴”在引用变量中时。此操作无需任何特定类型的转换逻辑。如果您使用GetType(),则变量类型仍然相同。

  2. 拆箱:它只是相反的操作。获取卡在引用对象中的值类型,并将其分配给值类型变量。同样,此操作不需要任何特定于类型的转换逻辑。

    因此,如果(int)s有效,那么它只是一个显式转换,而不是取消装箱操作,因为s.GetType()会返回System.String,而不是{{ 1}}。

答案 2 :(得分:0)

拳击/拆箱:将值类型转换为其对象表示,反之亦然(例如int和object)。

相比之下,ToString()方法是一个生成新字符串的操作,与装箱/演员/类型对话无关。

答案 3 :(得分:0)

在这个晚会上,但是......我不喜欢简单地阅读答案而没有背后的证据。我喜欢理解这个问题并分析可能的解决方案,看看它是否与我的理解相关。来自神杰夫里希特的正确广受欢迎的'CLR via C#'的复制和粘贴文字解释了这一点:

即使未装箱的值类型没有类型对象指针,您仍然可以调用由类型继承或覆盖的虚方法(如Equals,GetHashCode或ToString)。如果您的值类型覆盖其中一个虚方法,那么CLR可以非虚拟地调用该方法,因为值类型是隐式密封的,并且不能具有从它们派生的任何类型。此外,用于调用虚方法的值类型实例不会加框。但是,如果您对虚方法的重写调用基类型的方法实现,那么在调用基类型的实现时,值类型实例会被装箱,以便对堆对象的引用传递给this指针到基类方法。但是,调用非虚拟继承方法(例如GetType或MemberwiseClone)总是需要将值类型设置为框,因为这些方法是由System.Object定义的,因此方法期望this参数是一个引用该对象的指针。堆。

里普尔先生应该获得这本书的奖章。如果你还没有,那就去吧!然后你会得到它:))