C#基礎知識整理 基礎知識(19) 實值型別的裝箱和拆箱(二)

來源:互聯網
上載者:User
如果代碼中會造成編譯器的反覆裝箱,可改為手動裝箱,這樣來使代碼執行更快,看下面代碼:

            //手動裝箱            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)!

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.