如果代碼中會造成編譯器的反覆裝箱,可改為手動裝箱,這樣來使代碼執行更快,看下面代碼:
//手動裝箱 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));
通過前面的程式碼片段,我們再寫程式時就很容易判斷什麼時候實值型別要裝箱。無非就是當要擷取一個實值型別的引用時,就要裝箱。這裡也很清楚的可以看出實值型別與參考型別的區別:
1、實值型別不在託管堆中分配空間;而參考型別在執行個體化後就在堆上分配了類中指定的成員的的空間。
2、實值型別沒有堆上的對象的額外成員,即“類型對象指標”、“同步索引”。
未裝箱的實值型別沒有同步索引,因此不能使用該類型所在類的方法(比如lock)讓多個線程同步對這個執行個體的訪問。
雖然未裝箱的實值型別沒有類型對象指標,但仍可調用由類型繼承或重寫的虛方法,比如Equals,GetHashCode,ToString。如果實值型別重寫了其中任何一個虛方法,那麼CLR可以非虛地調用該方法,因為實值型別是隱式密封的,沒有任何類型能夠從它派生。此外,用於調用虛方法的實值型別執行個體不會被裝箱。如果重寫的虛方法要調用方法在基類中的實現,那麼在調用基類的實現時,實值型別執行個體會裝箱。因為這些方法是有System.Object定義的,所以這些方法期望this實參是指向堆上的一個對象的指標。
此外,將實值型別的一個未裝箱執行個體轉型為類型的某個介面是,要求執行個體進行裝箱。因為介面變數必須包含對堆上的一個對象的引用。看下面代碼:
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); } }
以上就是C#基礎知識整理 基礎知識(19) 實值型別的裝箱和拆箱(二)的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!