1. 程式人生 > 其它 >C#靜態成員和靜態類

C#靜態成員和靜態類

技術標籤:C#語言相關

static關鍵字定義靜態成員,靜態類

靜態成員
成員(欄位和方法)定義為static,那麼類中的所有例項都可以訪問它,所有的例項訪問的都是同一記憶體地址。
訪問:靜態成員直接通過類名訪問
生存週期:靜態欄位獨立於任何例項,不需要例項訪問。在使用之前就已經初始化好了(編譯器完成,不需要我們考慮)。靜態方法獨立於任何例項,不需要例項就可以訪問。但是靜態方法不能訪問例項的成員,只能訪問其它靜態成員,反過來是可以的(例項方法可以訪問靜態成員)
靜態建構函式
1,專門為初始化靜態欄位而生
2,在引用任何靜態成員之前和建立任何例項之前呼叫
3,與類同名,無返回值,使用static,無引數,無訪問修飾符(普通的建構函式與類同名,有訪問修飾符,無返回值)


靜態類
1,如果類中只包含靜態欄位和靜態方法,並且標為static 它就是靜態類
2,靜態類不能被例項化,也不能被繼承
3,靜態類中可以定義一個靜態構造
靜態類主要用於:基礎類庫(如數學庫)和擴充套件方法
如何擴充套件方法
1,如果有原始碼,直接修改
2,如果沒有原始碼,只是一個dll,但是如果它不是密閉類,那就可以派生子類擴充套件
3,如果以上條件都不滿足,我們可以寫靜態類對它進行擴充套件

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            PetGuild.HowToFeed(new Dog());
        }
    }
    
    class Dog { 
        // Dog這個類假設沒有原始碼,也不能派生,但我們要修改裡面的方法,就可以用下面的靜態類
        private string food;
        public Dog()
        {
            Food = "骨頭";
        }

        public string Food { get => food; set => food = value; }
    }

    static class PetGuild
    {
        public static void HowToFeed(Dog dog) { // 通過這個靜態類的靜態方法,把Dog傳遞過來
            dog.Food = "魚";
            Console.WriteLine("狗喜歡吃{0}",dog.Food);
        }
    }
}

最後輸出:狗喜歡吃魚

上面的程式碼可以簡化

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // 我們可以直接例項化Dog,擴展出來的PetGuild也可以供Dog使用,跟自己的成員一樣,可以點出來,完全看不出來它是靜態的
            Dog dog = new Dog();
            dog.HowToFeed();
        }
    }
    
    class Dog { // Dog這個類假設沒有原始碼,也不能派生,但我們要修改裡面的方法,就可以用下面的靜態類
        private string food;
        public Dog()
        {
            Food = "骨頭";
        }

        public string Food { get => food; set => food = value; }
    }

    static class PetGuild
    {
        public static void HowToFeed(this Dog dog) { // 注意這個地方,和上面的程式碼多了this,在這個靜態類的靜態方法的聲明當中加上了this關鍵字,在要擴充套件的類前面加上this
            dog.Food = "魚";
            Console.WriteLine("狗喜歡吃{0}",dog.Food);
        }
    }
}

總結擴充套件的要求:
1,擴充套件方法所屬的類要是靜態類,擴充套件方法也要是static
2,擴充套件方法的第一個引數型別,必須是this+類名