C# 装箱(boxing)与拆箱(unboxing) ToString VS boxing

In the .NET framework, there are two species of types–value types and reference types. This is relatively common in OO languages.

One of the important features of object oriented languages is the ability to handle instances in a type-agnostic manner. This is referred to as polymorphism. Since we want to take advantage of polymorphism, but we have two different species of types, there has to be some way to bring them together so we can handle one or the other the same way.

Now, back in the olden days (1.0 of Microsoft.NET), there weren’t this newfangled generics hullabaloo. You couldn’t write a method that had a single argument that could service a value type and a reference type. That’s a violation of polymorphism. So boxing was adopted as a means to coerce a value type into an object.

If this wasn’t possible, the framework would be littered with methods and classes whose only purpose was to accept the other species of type. Not only that, but since value types don’t truly share a common type ancestor, you’d have to have a different method overload for each value type (bit, byte, int16, int32, etc etc etc).

装箱的本质就是函数需要(堆内)对象的引用而不是对象自己。

ou’ve already got answers telling you that when ToString() is overridden for a value type, there will be no boxing when you call it, but it’s nice to have some way of actually seeing that.

Take the type int? (Nullable). This is a useful type because it is a value type, yet boxing may produce a null reference, and instance methods cannot be called through a null reference. It does have an overridden ToString() method. It does not have (and cannot have) an overridden GetType() method.

int? i = null;
var s = i.ToString(); // okay: initialises s to “”
var t = i.GetType(); // not okay: throws NullReferenceException

This shows that there is no boxing in the call i.ToString(), but there is boxing in the call i.GetType().

值类型调用object的方法时,如果方法未重写,则会装箱后再调用object的方法,因为object的方法需要的是堆内对象的引用。

ToString与装箱
显示调用ToString方法可避免装箱(因为值类型已经重写了ToString方法了),单从这点来看,确实有细微的性能提升。
但是,大多数时候并不是简单的ToString与装箱,比如匹配到string.Format(object…),那就变成先ToString后传递到Format方法,Format方法再ToString后才string.Concat。而且从整体来看,性能提升微乎其微。

Resharper对string.Format有ToString is redundant的建议,由此展开了讨论 https://resharper-support.jetbrains.com/hc/en-us/community/posts/206055279-Bad-Refactoring-Suggestion-on-int-ToString-

 

 

发表评论

电子邮件地址不会被公开。