程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 【C#進階系列】04 類型基礎,

【C#進階系列】04 類型基礎,

編輯:C#入門知識

【C#進階系列】04 類型基礎,


關於System.Object

  所有類型都從System.Object派生而來。

  System.Object的公共方法中ToString()一般是返回對象的類型的全名,只有Int32這些類型將其重寫後,新方法才會返回其值的字符串表示。

  其中還有兩個受保護的方法:

    MemberwiseClone:深復制。

    Finalize:在垃圾回收器判斷此對象應該被回收後,在對象的內存被實際回收前會調用此方法。

關於類型判斷和轉換:

  用is來判斷對象為某類型或者某類型的派生類,是為true,不是為false。

  用as轉換對象A為另一類型,成功則返回對象A的引用,失敗則返回null。

  以上兩種方法都不同於用()進行強制轉換,不會報異常。

  其實看代碼更好懂一點:

namespace MyTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var Troty123 = new Man();
            Console.WriteLine(Troty123 is Man);//True
            Console.WriteLine(Troty123 is People);//True
            Console.WriteLine(Troty123 is Animal);//False

            object fuckBoy = new Man();
            Console.WriteLine((fuckBoy as Man).ToString());//MyTest.Man
            Console.WriteLine((fuckBoy as People).ToString());//MyTest.Man
            Console.WriteLine(((fuckBoy as Animal)==null).ToString());//True
            Console.Read();
        }
    }
    class People {}
    class Man:People{}
    class Animal {}
}

 

using指令為命名空間或類型創建別名

using MySystemText = System.Text.StringBuilder;

namespace MyTest
{
    class Program
    {
        static void Main(string[] args)
        {
            MySystemText myText = new MySystemText();
        }
    }
}

用於解決引用不同命名空間時,兩個命名空間中有相同名稱但功能不同的類型的問題。

 

一個關於堆棧和類的故事

先貼出示例代碼

  class Program
    {
        static void Main(string[] args)
        {
            Show();
        }
        static void  Show() {
            People Troy123 = new People();
            Troy123.Die();
            Console.Read();
        }
    }
    class People{
        int age;
        public void Die() { }
    }

 

 

我們就講一下Show被調用後的故事:

堆變化

首先JIT編譯器會吧Show的IL代碼全部轉換為本機CPU指令,這個時候就已經知道了本函數中會用到People這個類型。

然後生成了一個System.Type類型的實例,我們這裡叫People的類型對象A好了,裡面有指向System.Type類型對象的指針,同步塊索引,People的靜態字段以及People的函數的入口。

棧變化

Show被調用後會先判斷Show是否有參數傳進來,有就壓到棧中。(顯然並沒有)

然後Show在Main函數中的代碼的地址會被壓到棧中。

然後類型Troy123 的引用地址被壓入棧中。

堆變化

 

然後生成People類的實例,此實例包含People類的實例字段以及其基類的實例字段。

且此實例的類型對象指針指向之前的A的地址。(多個People類的實例的類型對象指針都指向這一個地址)

然後調用Die(),

  如果Die函數是個虛函數,且實例是People的派生類Man的實例,且此派生類的Die函數override類People的Visual的Die函數。那麼就應該實現類Man中的Die函數。(很顯然不是)

  如果不符合上面這種情況,那麼就按照   調用Die函數的那個變量Troy123的類型   中的Die函數來實現,也就是說如果Troy123是People類型就實現People的Die,如果是派生類Man類型就實現Man的Die。(而顯然上面的代碼實現People的Die)也就是說即使是People Troy123=new Man();實際上也是實現People的Die。

 

棧變化

如果Show函數結束,那麼CPU的指令指針會指向之前壓到棧中的返回地址,然後退棧幀,然後此時棧幀反應Main函數的堆棧情況。

堆變化

而此時People的實例已經沒有被任何變量引用了,那麼此時就會等待被垃圾回收器回收。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved