天天看點

C#你必須知道的25個基礎概念

1.靜态變量和非靜态變量的差別?

靜态變量:靜态變量使用 static 修飾符進行聲明 ,在所屬類被裝載時建立,通過類進行通路,所屬類的

所有執行個體的同一靜态變量都是同一個值。

非靜态變量:不帶有static 修飾符聲明的變量稱做非靜态變量,在類被執行個體化時建立,通過對象進行訪

問,同一個類的不同執行個體的同一非靜态變量可以是不同的值。

2.const 和 static readonly 差別?

const:用const 修飾符聲明的成員叫常量,是在編譯期初始化并嵌入到用戶端程式。

static readonly:用static readonly 修飾符聲明的成員依然是變量,隻不過具有和常量類似的

使用方法:通過類進行通路、初始化後不可以修改。但與常量不同的是這種變量是在運作期初始化。

3.extern 是什麼意思?

extern:修飾符用于聲明由程式集外部實作的成員函數,經常用于系統API函數的調用。

注意:和DllImport一起使用時要加上static修飾符,也可以用于對于同一程式集不同版本元件的

調用(用extern聲明别名),不能與abstract修飾符同時使用。

4.abstract 是什麼意思?

abstract修飾符可以用于類、方法、屬性、事件和索引訓示器(indexer),表示其為抽象成員。

abstract不可以和 static 、virtual 、override 一起使用。

聲明為abstract成員可以不包括實作代碼,但隻有類中還有未實作的抽象成員,該類就不可以被執行個體化,

通常用于強制繼承類必須實作某一成員。

5.internal 修飾符起什麼作用?

internal 修飾符可以用于類型或成員,使用該修飾符聲明的類型或成員隻能在同一程集内通路,

接口的成員不能使用 internal 修飾符

6.sealed 修飾符是幹什麼的?

sealed修飾符表示密封,用于類時,表示該類不能再被繼承,不能和abstract同時使用,

因為這兩個修飾符在含義上互相排斥,用于方法和屬性時,表示該方法或屬性不能再被繼承,

必須和override關鍵字一起使用,因為使用sealed修飾符的方法或屬性肯定是基類中相應的虛成員,

通常用于實作第三方類庫時不想被用戶端繼承,或用于沒有必要再繼承的類以防止濫用繼承造成

層次結構體系混亂。恰當的利用sealed修飾符也可以提高一定的運作效率。

7.override 和 overload 的差別?

override 表示重寫,用于繼承類對基類中虛成員的實作。

overload 表示重載,用于同一個類中同名方法不同參數(包括類型不同或個數不同)的實作。

8.什麼是索引訓示器?

實作索引訓示器(indexer)的類可以象數組那樣使用其執行個體後的對象,但與數組不同的是索引訓示器的

參數類型不僅限于int,簡單來說,其本質就是一個含參數屬性。

9.new 修飾符是起什麼作用?

new 修飾符與 new 操作符是兩個概念。

new 修飾符用于聲明類或類的成員,表示隐藏了基類中同名的成員。而new 操作符用于執行個體化一個類型。

new 修飾符隻能用于繼承類,一般用于彌補基類設計的不足。

new 修飾符和override修飾符不可同時用在一個成員上,因為這兩個修飾符在含義上互相排斥。

10.this 關鍵字的含義?

this是一個保留字,僅限于構造函數和方法成員中使用。

在類的構造函數中出現表示對正在構造的對象本身的引用,

在類的方法中出現表示對調用該方法的對象的引用。

在結構的構造上函數中出現表示對正在構造的結構的引用,

在結構的方法中出現表示對調用該方法的結果的引用。

this保留字不能用于靜态成員的實作裡,因為這時對象或結構并未執行個體化。

在C#系統中,this 實際上是一個常量,是以不能使用this++這樣的運算。

this保留字一般用于限定同名的隐藏成員、将對象本身做為參數、聲明索引通路器、判斷傳入參數的對象是否為本身。

11.可以使用抽象函數重寫基類中的虛函數嗎?

可以,但需使用new修飾符顯式聲明,表示隐藏了基類中該函數的實作。

12.密封類可以有虛函數嗎?

可以,基類中的虛函數将隐式的轉化為非虛函數,但密封類本身不能再增加新的虛函數。

13.屬性通路器?

如果基類中的虛屬性隻有一個屬性通路器,那麼繼承類重寫該屬性後可以有幾個屬性通路器?如果基類中有get和set兩個呢?

如果基類中的虛屬性隻有一個屬性通路器,那麼繼承類重寫該屬性後也應隻有一個。

如果基類中有get和set兩個屬性通路器,那麼繼承類中可以隻有一個也可以同時有兩個屬性通路器。

14.abstract、virtual、override?

abstract 可以和 virtual 一起使用嗎?可以和 override 一起使用嗎?

abstract 修飾符不可以和 static、virtual 和 override 修飾符一起使用。

15.接口可以包含哪些成員?

接口可以包含屬性、方法、索引訓示器和事件,但不能包含常量、域、操作符、構造函數和析構函數,而且也不能包含任何靜态成員。

16.類和結構的差別?

類:類是引用類型在堆上配置設定,類的執行個體進行指派隻是複制了引用,都指向同一段實際對象配置設定的記憶體,

類有構造和析構函數,類可以繼承和被繼承。

結構:結構是值類型在棧上配置設定(雖然棧的通路速度比較堆要快,但棧的資源有限放),

結構的指派将配置設定産生一個新的對象。結構沒有構造函數,但可以添加。結構沒有析構函數,

結構不可以繼承自另一個結構或被繼承,但和類一樣可以繼承自接口。

17.接口的多繼承會帶來哪些問題?

C# 中的接口與類不同,可以使用多繼承,即一個子接口可以有多個父接口。

但如果兩個父成員具有同名的成員,就産生了二義性(這也正是C#中類取消了多繼承的原因之一),這時在實作時最好使用顯式的聲明。

18.抽象類和接口的差別?

抽象類(abstract class)可以包含功能定義和實作,

接口(interface)隻能包含功能定義,抽象類是從一系列相關對象中抽象出來的概念,是以反映的是事物的

内部共性,接口是為了滿足外部調用而定義的一個功能約定, 是以反映的是事物的外部特性,分析對象,

提煉内部共性形成抽象類,用以表示對象本質,即“是什麼”,為外部提供調用或功能需要擴充時優先使用接口。

19.别名訓示符是什麼?

通過别名訓示符我們可以為某個類型起一個别名,主要用于解決兩個命名空間内有同名類型的沖突或

避免使用備援的命名空間,别名訓示符隻在一個單元檔案内起作用。

20.如何釋放非托管資源?

.NET平台在記憶體管理方面提供了GC(Garbage Collection),負責自動釋放托管資源和記憶體回收的

工作,但它無法對非托管資源進行釋放,這時我們必須自己提供方法來釋放對象内配置設定的非托管資源,

比如你在對象的實作代碼中使用了一個COM對象,最簡單的辦法,可以通過實作

protected void Finalize()(析構函數會在編譯時變成這個東東)來釋放非托管資源,

因為GC在釋放對象時會檢查該對象是否實作了 Finalize() 方法,如果是則調用它。

有一種更好的,那就是通過實作一個接口顯式的提供給客戶調用端手工釋放對象的方法,

而不是傻傻的等着GC來釋放我們的對象(何況效率又那麼低),

System命名空間内有一個IDisposable接口,拿來做這事非常合适,就省得我們自己再聲明一個接口了。

另外補充一句,這種實作并不一定要使用了非托管資源後才用,如果你設計的類會在運作時有大些的

執行個體(象GIS中的Geometry),為了優化程式性能,你也可以通過實作該接口讓客戶調用端在确認

不需要這些對象時手工釋放它們。

21.P/Invoke是什麼?

在受控代碼與非受控代碼進行互動時會産生一個事務(transition),

這通常發生在使用平台調用服務(Platform Invocation Services),即P/Invoke,

如調用系統的API或與COM對象打交道,通過System.Runtime.InteropServices命名空間,

雖然使用Interop非常友善,但據估計每次調用事務都要執行10到40條指令,算起來開銷也不少,

是以我們要盡量少調用事務,如果非用不可,建議本着一次調用執行多個動作,

而不是多次調用每次隻執行少量動作的原則。

22.StringBuilder 和 String 的差別?

String雖然是一個引用類型,但在指派操作時會産生一個新的對象,而StringBuilder則不會,

是以在大量字元串拼接或頻繁對某一字元串進行操作時最好使用StringBuilder,不要使用String。

23.explicit 和 implicit 的含義?

explicit和implicit屬于轉換運算符,如用這兩者可以讓我們自定義的類型支援互相交換,

explicti表示顯式轉換,如從A->B必須進行強制類型轉換(B=(B)A),

implicit表示隐式轉換,如從B->A隻需直接指派(A=B),

隐式轉換可以讓我們的代碼看上去更漂亮、更簡潔易懂,是以最好多使用 implicit 運算符。

不過!如果對象本身在轉換時會損失一些資訊(如精度),那麼我們隻能使用 explicit 運算符,以便在編譯期就能警告客戶調用端。

24.params 有什麼用?

params關鍵字在方法成員的參數清單中使用,為該方法提供了參數個數可變的能力,

它在隻能出現一次并且不能在其後再有參數定義,之前可以。

25.什麼是反射

反射,Reflection,通過它我們可以在運作時獲得各種資訊,

如程式集、子產品、類型、字段、屬性、方法和事件,

通過對類型動态執行個體化後,還可以對其執行操作,一般用于插件式架構程式和設計模式的實作,

當然反射是一種手段可以充分發揮其能量來完成你想做的任何事情。