c#靜態變量和非靜態變量的區別

c#靜態變量和非靜態變量的區別

  靜態變量的類型說明符是static。靜態變量當然是屬於靜態存儲方式,但是屬於靜態存儲方式的量不一定就是靜態變量,例如外部變量雖屬於靜態存儲方式,但不一定是靜態變量,必須由 static加以定義後才能成爲靜態外部變量,或稱靜態全局變量。

詳解:

一,靜態資源在首次訪問時會調用靜態構造器創建類類型對象(靜態屬於類,動態屬於對象,靜態被靜態構造器創建,動態被普通構造創建,所以實例對象的時候,靜態不會被重新構造),

二,類型對象的生存週期是整個應用程序域的生存週期,也就說被訪問過的靜態資源,只有它所在的應用程序域被卸載時纔會被卸載,靜態變量始終存在着,也就是說它的生存期爲整個源程序。

三,當頁面第一次被訪問的時候,相當於頁面被構造,靜態變量被靜態構造器初始化,然後再次訪問這個頁面的時候,雖然非靜態資源重新被構造,但是此時靜態資源並不被重新構造並一直存在(也可以用來做頁面狀態保持,不過不建議用,因爲一直佔用資源,不像session還定時被回收),直至應用程序域被回收。(構造類靜態若局部未賦以初值,則由系統自動賦以0值。 )

四,如果是application級的,用靜態變量來代替application對象是可以的,優點是速度快(存儲區域不同,而且不用裝箱拆箱),缺點是沒有application對象通用(application對象可以隨意存儲任何對象)

五,就是頁面的靜態變量頁面第一次被訪問時被初始化,在應用程序域一直保存,動態變量只在一個http請求作用(每次http請求相當於實例一次頁面這個類)

六,靜態變量在靜態存儲區內分配存儲單元。在程序整個運行期間都不釋放。而變量屬於動態存儲類別,存儲在動態存儲區空間(而不是靜態存儲區空間),函數調用結束後即釋放。

七,由靜態構造而聯想到的問題:

複製代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StaticDemo
{
class Program
{
static void Main(string[] args)
{
//創建包含靜態構造函數的類實例時和訪問包含靜態構造函數的靜態成員時,先調用靜態構造函數,無論創建了多少個類實例和調用多少次靜態成員,其靜態構造函數都只調用了一次。
StaticTest s = new StaticTest();
StaticTest s2
= new StaticTest();
//s.Say(); //無法使用實例來引用來訪問靜態成員
StaticTest.Say();
StaticTest.Say();
Console.WriteLine(StaticTest.constdemo);
//調用靜態類的靜態方法,其中的靜態構造也是隻被調用一次
StaticTest2.Say();
StaticTest2.Say();
Console.ReadKey();
}
}
public class StaticTest
{
//靜態構造方法不可以被修飾符public等修飾,靜態構造必須無參數
//public static StaticTest()
static StaticTest()
{
Console.WriteLine(
非靜態類的靜態構造方法只被調用一次);
}
//無參數的構造函數可以與靜態構造函數共存。儘管參數列表相同,但一個屬於類,一個屬於實例,所以不會衝突。
public StaticTest() {
Console.WriteLine(
非靜態類的非靜態構造方法可以共存);
}
//雖然字段不能聲明爲 static const,但 const 字段的行爲在本質上是靜態的。
//這樣的字段屬於類,不屬於類的實例。因此,可以同對待靜態字段一樣使用 ClassName.MemberName 表示法來訪問 const 字段
public const int constdemo = 1;
public static void Say()
{
Console.WriteLine(
非靜態類的的靜態方法);
}
}
public static class StaticTest2
{
static StaticTest2()
{
Console.WriteLine(
靜態類的靜態構造方法只被調用一次);
}

public static void Say()
{
Console.WriteLine(
靜態類的的靜態方法);
}
}
}

不管是靜態類還是非靜態類的靜態構造方法都只能被調用 一次。
在這裏插入圖片描述
靜態類不能實例化,只能直接被引用

在這裏插入圖片描述

在這裏插入圖片描述

複製代碼

 

1》雖然字段不能聲明爲 static const,但 const 字段的行爲在本質上是靜態的。

2》靜態構造方法不可以被修飾符public等修飾,靜態構造必須無參數

3》創建包含靜態構造函數的類實例時和訪問包含靜態構造函數的靜態成員時,先調用靜態構造函數,無論創建了多少個類實例和調用多少次靜態成員,其靜態構造函數都只調用了一次。

4》無參數的構造函數可以與靜態構造函數共存。儘管參數列表相同,但一個屬於類,一個屬於實例,所以不會衝突。

八,那靜態方法能不能被繼承和重寫?看如下代碼,

複製代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StaticOrOverride
{
class Program
{
static void Main(string[] args)
{
ParentTest p
= new ParentTest();
ParentTest.Say();
//而靜態方法能被父類繼承使用
}
}
public class Test
{
//public static virtual void Say() //錯誤:靜態成員“StaticOrOverride.Test.Say()”不能標記爲 override、virtual 或 abstract,也正是如此。靜態成員不可以與被重寫
//{
// Console.WriteLine(“靜態方法”);
//}
public static void Say()
{
Console.WriteLine(
靜態方法);
}
}
public class ParentTest : Test
{
}
}

複製代碼

1》父類的靜態方法可以被子類繼承,但是不能重寫,爲什麼呢?

重寫的意思是重新定義父類的虛函數,但是虛函數是動態綁定的,而靜態方法是靜態綁定的,所以靜態函數必然不能是虛函數,同時靜態成員不能標記爲 override、virtual 或 abstract,也就不存在所說的重寫了.

九,動態綁定和靜態綁定是什麼意思呢?

1》動態綁定:只有在程序運行時才能決定調用哪個函數;

2》 靜態綁定:編譯時就可以決定調用哪個函數;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章