我在拳击和拆箱方面有点困惑。根据其定义
拳击是将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;
这是拳击和拆箱的一个例子吗?
答案 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.String
和System.Int32
之间未定义显式转换。
通过以下方式考虑它,以了解什么是拳击和取消装箱:
拳击:当你获取一个值类型并将其“粘贴”在引用变量中时。此操作无需任何特定类型的转换逻辑。如果您使用GetType()
,则变量类型仍然相同。
拆箱:它只是相反的操作。获取卡在引用对象中的值类型,并将其分配给值类型变量。同样,此操作不需要任何特定于类型的转换逻辑。
因此,如果(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参数是一个引用该对象的指针。堆。
里普尔先生应该获得这本书的奖章。如果你还没有,那就去吧!然后你会得到它:))