If the code will cause repeated boxing by the compiler, you can change it to manual boxing to make the code execute faster. See the following code:
//手动装箱 Int32 v = 5; //由于string.Format的参数是object类型,所以这里会造成三次装箱。 Console.WriteLine(string.Format("{0},{1},{2}", v, v, v)); //修改一下,当然这只是一个小技巧,比如程序中对同一个值的同一个操作执行多次, //应该都是要先执行一次,然后再使用的。 Object o = v;//装箱一次 Console.WriteLine(string.Format("{0},{1},{2}", o, o, o));
Through the previous code segment, we can write When programming, it is easy to tell when a value type needs to be boxed. It's nothing more than boxing when you want to get a reference to a value type. Here we can also clearly see the difference between value types and reference types:
1. Value types do not allocate space in the managed heap; while reference types allocate the members specified in the class on the heap after instantiation. space.
2. Value types do not have additional members of objects on the heap, namely "type object pointer" and "synchronization index".
The unboxed value type does not have a synchronized index, so the method of the class in which the type is located (such as lock) cannot be used to allow multiple threads to synchronize access to this instance.
Although unboxed value types do not have type object pointers, virtual methods inherited or overridden by the type can still be called, such as Equals, GetHashCode, and ToString. If a value type overrides any of these virtual methods, the CLR can call that method non-virtually because the value type is implicitly sealed and no type can be derived from it. Additionally, value type instances used to call virtual methods are not boxed. If the overridden virtual method calls the method's implementation in the base class, the value type instance will be boxed when the base class implementation is called. Because these methods are defined by System.Object, these methods expect the this argument to be a pointer to an object on the heap.
In addition, converting an unboxed instance of a value type to an interface of the type requires the instance to be boxed. Because the interface variable must contain a reference to an object on the heap. Look at the code below:
class Program { static void Main(string[] args) { Point p1 = new Point(10, 10); Point p2 = new Point(20, 20); //调用ToString不装箱,这里ToString是一个虚方法 Console.WriteLine(p1.ToString()); //GetType是一个非虚方法,p1要装箱 Console.WriteLine(p1.GetType()); //这里调用的是public int CompareTo(Point p) //p2不会装箱 Console.WriteLine(p1.CompareTo(p2)); //p1要装箱,这就是将未装箱的值类型转为类型的某个接口时 IComparable c = p1; Console.WriteLine(c.GetType()); //这里调用的是public Int32 CompareTo(Object o), //而且c本来就是一个引用,因此不装箱了 Console.WriteLine(p1.CompareTo(c)); //这里调用的是c的CompareTo方法,参数是object型的 //所以要对p2装箱 Console.WriteLine(c.CompareTo(p2)); //对c拆箱,并复制值到p2中 p2 = (Point)c; Console.WriteLine(p2.ToString()); } } internal struct Point : IComparable { private Int32 x; private Int32 y; public Point(Int32 x, Int32 y) { this.x = x; this.y = y; } public override string ToString() { return string.Format("{0},{1}", x, y);//这里装箱两次,不知道有没好办法。 } public int CompareTo(Point p) { return Math.Sign(Math.Sqrt(x * x + y * y) - Math.Sqrt(p.x * p.x + p.y * p.y)); } public Int32 CompareTo(Object o) { if (GetType() != o.GetType()) { throw new ArgumentException("o is not Point."); } return CompareTo((Point)o); } }
The above is the basic knowledge of C# (19) Boxing and unboxing of value types (2). For more related content, please pay attention to the PHP Chinese website (www .php.cn)!