1. 程式人生 > >你必須知道的25個C#基礎概念

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

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 修飾符不可以和 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,通過它我們可以在執行時獲得各種資訊,
如程式集、模組、型別、欄位、屬性、方法和事件,
通過對型別動態例項化後,還可以對其執行操作,一般用於外掛式框架程式和設計模式的實現,
當然反射是一種手段可以充分發揮其能量來完成你想做的任何事情。