第四周總結數據庫
1、static用於修飾類、字段、屬性、方法以及構造方法等,被static修飾的成員爲靜態成員,靜態成員包括靜態字段、靜態屬性、靜態方法、靜態方法、靜態構造方法注意靜態類不是靜態成員c#
4.8.1靜態字段:靜態字段是被static修飾的字段,它不屬於任何對象,只屬於類,並且只能經過「類名.靜態字段名」的方式來訪問。設計模式
使用方法:例如某個學校全部學生共享一個學校名稱,此時徹底沒必要在每一個學生對象所佔用的內存空間都定義一個字段來存儲這個學校名稱,此時可定義一個靜態字段來表示學校名稱讓全部對象來共享。具體代碼以下:安全
注意: 不管建立多少個Student對象,靜態字段schoolName的值都不會改變,要想改變靜態字段的值只有經過「類命.靜態字段名」的方式併爲其從新賦值,如:多線程
Student.schoolName=「School「併發
這樣Student類的靜態字段值就變成了「school「函數
引用:「不管建立多少個Student對象,靜態字段schoolName的值都不會改變「爲何不會改變?工具
答案是這樣的,內存能夠物理劃分紅五塊堆、棧、靜態存儲區、程序代碼區、文字區,不用說靜態字段是存儲在靜態存儲區,對象存儲在程序代碼區,因此不管建立多少個Student對象,靜態字段schoolName的值都不會改變,注意:靜態字段一旦被使用便會一直存在直到程序生命週期結束,因此靜態成員很佔用資源。性能
補充幾個關於靜態字段的問題:網站
靜態字段與非靜態字段的區別:
一、靜態字段經過類名訪問,非靜態字段通多對象名訪問
二、靜態字段屬於類,爲全部對象所用,非靜態字段屬於對象,爲對象專用;
3 靜態字段用使用static修飾符來修飾,非靜態不用;
靜態屬性:用static修飾的屬性成爲靜態屬性,調用方式同靜態字段同樣,
靜態類總結:
一、 只要是靜態成員,都要使用類名去調用,非靜態成員都要使用對象名去調用
二、 靜態函數中,只能訪問靜態成員,不能訪問實例成員,實例函數中,既可使用實例成員,也可使用靜態成員。
三、靜態類中只能出現靜態成員。
4.靜態類不能建立對象,即不容許被實例化。
5.非靜態類能夠包含靜態的方法字段、屬性或事件,
6.不管對一個類創健多少個實例,它的靜態成員都只有一個副本,
7.靜態方法和屬性不能訪問其包含類型中的非靜態字段和事件。
8.靜態方法只能被重載,而不能被重寫,由於靜態方法不屬於類的實例成員:
9.雖然字段不能聲明爲static const,但const字段的行爲在本質上是靜態的。這樣的字段屬於類,
不屬於類的實例。所以,能夠同對待靜態字段樣使用ClassName.MemberName表示法來訪問const字段
10.靜態字段屬於類,井爲類所用。而非靜態字段屬於對象,只能被特定的對象專有。
11.在跟類的實例無關,只跟類有關的狀況下使用靜態成員(如Math類的數學計算方法等不須要建立多個實例)
12.使用靜態成員能夠避免建立對象時引入一次對象的構造和一次對象的析構
13.注意,Connection鏈接對象不可以使用static,靜態化致使大最併發使用相同連核池,而鏈接池是有個數限制的,會致使數據庫鏈接池達到最大值而不能繼續訪問網站。
靜態類的主要特性:
1僅包含靜態成員
2.沒法實例化
3.是密封的
4.不能包含實例構造函數。
關於靜態類問題補充:
何時使用靜態類?
1.常用的類,即「工具類」
三、 須要存儲全局可見的數據。
私有構造器與靜態類的區別:
1) 私有構造器方式仍然能夠從類的內部對類進行實例化,而靜態類禁止從任何地方實例化類其中包括從類自身內部
2)在使用私有構造器的類中,是容許有實例成員的,而C# 2.0和更高版本的編譯器不容許靜態類有任何實例成員,
使用靜態類的優勢:
使用靜態類的優勢在於,編譯器可以執行檢查似確保不致偶然地添加實例成員,編譯器將保證不會建立此類的實假靜態類的另外一個特徵在於, C#編譯器會自動方sealed這個關鍵字將類指定爲不可擴展,換言之,不能從它派生出其餘類。
3.靜態方法只能訪問靜態成員,實例方法能夠訪問靜態和實例成員麼?
之因此不容許靜態方法訪問實例成員變量,是由於實例成員變量是屬於某個對象的,
而靜態方法在執行時,並不必定存在對象。一樣,由於實例方法能夠訪問實例成員變量,
若是容許靜態方法調用實例方法,將間接地容許它使用實例成員變量,因此它也不能調用實例方法。基於一樣的道理,靜態方法中也不能使用關鍵字this
main()方法是一個典型的靜態方法,它一樣遵循通常靜態方法的規則,因此它能夠由系統在建立對象以前就調用。
靜態構造方法:靜態構造方法的做用是初始化靜態成員,一個類只能有一個靜態構造方法,該靜態構造方法沒有任何修飾符,也沒有參數能夠被定義在靜態類和非靜態類中,注意靜態構造方法會在程序建立第一個實例或引用任何靜態成員以前,完成類中靜態成員的初始化。
在使用靜態構造函數的時候應該注意幾點:
一、靜態構造函數既沒有訪問修飾符,也沒有參數。由於是.NET調用的,因此像public和private等修飾符就沒有意義了。
二、是在建立第一個類實例或任何靜態成員被引用時, .NET將自動調用靜態構造函數來初始化類,也就是說咱們沒法直接調用靜態構造函數,也就沒法控制何時執行靜態構造函數了。
三、一個類只能有一個靜態構造函數。
4無參數的構造函數能夠與靜態構造函數共存。儘管參數列表相同,但一個屬於類,一個屬於實例,因此不會衝突。
五、最多隻運行一次。
6.靜態構造函數不能夠被繼承。
7.若是沒有寫靜態構造函數,而類中包含帶有初始值設定的靜態成員,那麼編譯器會自動生成默認的靜態構造函數。
單例模式:單例模式是c#中的一種設計模式,它是指在設計一個類時,須要保證整個程序在運行期間只存在一個實例對象。單例模式(Singleton)是幾個建立模式中最對立的一個,它的主要特色不是根據用戶程序調用生成一個新的實例,而是控制某個類型的實例惟一性,咱們知道它包含的角色只有一個,就是Singleton,它擁有一個私有構造函數,這確保用戶沒法經過new直接實例它。除此以外,該模式中包含一個靜態私有成員變量instance與靜態公有方法Instance()。Instance()方法負責檢驗並實例化本身,而後存儲在靜態成員變量中,以確保只有一個實例被建立。做用:單例模式就是保證在整個應用程序的生命週期中,在任什麼時候刻,被指定的類只有一個實例,併爲客戶程序提供一個獲取該實例的全局訪問點。
單例模式三種寫法
1.經典模式:
public class Singleton
{ private static Singleton instance; private Singleton()
{
} public static Singleton GetInstance()
{ if(instance==null)
{
instance=new Singleton();
} return instance;
}
}
在這種經典模式下,沒有考慮線程併發獲取實例問題,便可能出現兩個線程同時獲取instance實例,且此時其爲null時,就會出現兩個線程分別建立了instance,違反了單例規則。所以,需對上面代碼修改。
2 多線程下的單例模式
public class Singleton
{ private static Singleton instance; private static object _lock=new object(); private Singleton()
{
} public static Singleton GetInstance()
{ if(instance==null)
{ lock(_lock)
{ if(instance==null)
{
instance=new Singleton();
}
}
} return instance;
}
}
上述代碼使用了雙重鎖方式較好地解決了多線程下的單例模式實現。先看內層的if語句塊,使用這個語句塊時,先進行加鎖操做,保證只有一個線程能夠訪問該語句塊,進而保證只建立了一個實例。再看外層的if語句塊,這使得每一個線程欲獲取實例時沒必要每次都得加鎖,由於只有實例爲空時(即須要建立一個實例),才需加鎖建立,若果已存在一個實例,就直接返回該實例,節省了性能開銷。
3 餓漢模式
public sealed class Singleton
{ private static readonly Singleton instance=new Singleton(); private Singleton()
{
} public static Singleton GetInstance()
{ return instance;
}
}
上面使用的readonly關鍵能夠跟static一塊兒使用,用於指定該常量是類別級的,它的初始化交由靜態構造函數實現,並能夠在運行時編譯。在這種模式下,無需本身解決線程安全性問題,CLR會給咱們解決。由此能夠看到這個類被加載時,會自動實例化這個類,而不用在第一次調用GetInstance()後才實例化出惟一的單例對象。
單例模式的優勢
單例模式(Singleton)會控制其實例對象的數量,從而確保訪問對象的惟一性。
實例控制:單例模式防止其它對象對本身的實例化,確保全部的對象都訪問一個實例。
伸縮性:由於由類本身來控制實例化進程,類就在改變實例化進程上有相應的伸縮性。
單例模式的缺點:
系統開銷。雖然這個系統開銷看起來很小,可是每次引用這個類實例的時候都要進行實例是否存在的檢查。這個問題能夠經過靜態實例來解決。
開發混淆。當使用一個單例模式的對象的時候(特別是定義在類庫中的),開發人員必需要記住不能使用new關鍵字來實例化對象。由於開發者看不到在類庫中的源代碼,因此當他們發現不能實例化一個類的時候會很驚訝。
對象生命週期。單例模式沒有提出對象的銷燬。在提供內存管理的開發語言(好比,基於.NetFramework的語言)中,只有單例模式對象本身才能將對象實例銷燬,由於只有它擁有對實例的引用。在各類開發語言中,好比C++,其它類能夠銷燬對象實例,可是這麼作將致使單例類內部的指針指向不明。
單例適用性
使用Singleton模式有一個必要條件:在一個系統要求一個類只有一個實例時才應當使用單例模式。反之,若是一個類能夠有幾個實例共存,就不要使用單例模式。
不要使用單例模式存取全局變量。這違背了單例模式的用意,最好放到對應類的靜態成員中。
不要將數據庫鏈接作成單例,由於一個系統可能會與數據庫有多個鏈接,而且在有鏈接池的狀況下,應當儘量及時釋放鏈接。Singleton模式因爲使用靜態成員存儲類實例,因此可能會形成資源沒法及時釋放,帶來問題。
嵌套類:從做用域的角度看,嵌套類被隱藏在外圍類之中,該類名只能在外圍類中使用。若是在外圍類的做用域內使用該類名時,須要加名字限定。從訪問權限的角度來看,嵌套類名與它的外圍類的對象成員名具備相同的訪問權限規則。不能訪問嵌套類的對象中的私有成員函數,也不能對外圍類的私有部分中的嵌套類創建對象。嵌套類中說明的成員不是外圍類中對象的成員,反之亦然。嵌套類的成員函數對外圍類的成員沒有訪問權,反之亦然。國此,在分析嵌套類與外圍類的成員訪問關係時,每每把嵌套類看做非嵌套類來處理.
由引可見,嵌套類僅僅是語法上的嵌入。
嵌套類能夠很好的適用於「須要一個輔助類來代替包含類工做的情形」。例如,容器類可能維護了一組對象,假設你須要一些工具來迭代這些被包含的對象,並容許執行迭代的外部用戶維護一個表明迭代過程當中當前位置的標記或迭代器——這能夠改變容器類的內部行爲而不會破壞使用容器類的代碼,帶來的巨大的靈活性。這個時候嵌套類就能夠提供一個很好的解決方案。
匿名類:匿名類型的使用場景 當類中只定義了一些字段和屬性,沒有構造函數、方法、委託事件等比較複雜的成員,並且這個類的使用頻率不高時,咱們就可使用匿名類型。二、匿名類型的定義 定義一個匿名類型時,須要使用var關鍵字和對象初始化語法。
var:編譯器會在編譯時自動生成新類的定義。
初始化:編譯器會爲類建立私有的字段和(只讀)屬性。
特色:
1. 只能包含公共變量
2.聲明匿名類時必須初始化變量
3.沒法使用靜態變量
4.沒法爲匿名類定義類型
5.函數簽名不指定變量類型;
對象初始化器:在一個類中,一般時使用構造方法來爲屬性賦值,當一個類中屬性過多時,不可能爲每種狀況都建立一個構造方法,此時可使用對象初始化器來爲屬性賦值,語法格式以下:
類名 變量名=new 類名(){屬性名=值、屬性名=值…..};
對象初始化器與構造方法的異同比較
相同點是:二者均可以完成對象屬性的初始化
不一樣點是:
構造函數具備強制性,而對象初始化器沒有強制性。
獨享初始化只能完成屬性初始化;而構造方法是寫在類裏面。
構造方法在.NET1.0就有。
對象初始化器在.NET3.0以上版本纔有。