C#25問

1.靜態變量和非靜態變量的區別?
2.const 和 static readonly 區別?
3.extern 是什麼意思?
4.abstract 是什麼意思?
5.internal 修飾符起什麼作用?
6.sealed 修飾符是幹什麼的?
7.override 和 overload 的區別?
8.什麼是索引指示器?
9.new 修飾符是起什麼作用?
10.this 關鍵字的含義?
11.可以使用抽象函數重寫基類中的虛函數嗎?
12.密封類可以有虛函數嗎?
13.如果基類中的虛屬性只有一個屬性訪問器,那麼繼承類重寫該屬性後可以有幾個屬性訪問器?如果基類中有 get 和 set 兩個呢?
14.abstract 可以和 virtual 一起使用嗎?可以和 override 一起使用嗎?
15.接口可以包含哪些成員?
16.類和結構的區別?
17.接口的多繼承會帶來哪些問題?
18.抽象類和接口的區別?
19.別名指示符是什麼?
20.如何釋放非託管資源?
21.P/Invoke是什麼?
22.StringBuilder 和 String 的區別?
23.explicit 和 implicit 的含義?
24.params 有什麼用?
25.什麼是反射?

1.靜態變量和非靜態變量的區別?
答:

靜態變量:

靜態變量使用 static 修飾符進行聲明

在所屬類被裝載時創建

通過類進行訪問

所屬類的所有實例的同一靜態變量都是同一個值

非靜態變量:

不帶有 static 修飾符聲明的變量稱做非靜態變量

在類被實例化時創建

通過對象進行訪問

同一個類的不同實例的同一非靜態變量可以是不同的值

2.const 和 static readonly 區別?

答:

const

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

static readonly

用 static readonly 修飾符聲明的成員依然是變量,只不過具有和常量類似的使用方法:通過類進行訪問、初始化後不可以修改。但與常量不同的是這種變量是在運行期初始化

3.extern 是什麼意思?
答:

extern 修飾符用於聲明由程序集外部實現的成員函數

經常用於系統API函數的調用(通過 DllImport )。注意,和DllImport一起使用時要加上 static 修飾符

也可以用於對於同一程序集不同版本組件的調用(用 extern 聲明別名)

不能與 abstract 修飾符同時使用


4.abstract 是什麼意思?
答:

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

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

聲明爲 abstract 成員可以不包括實現代碼,但只有類中還有未實現的抽象成員,該類就不可以被實例化,通常用於強制繼承類必須實現某一成員


4.abstract 是什麼意思?
答:

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

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

聲明爲 abstract 成員可以不包括實現代碼,但只有類中還有未實現的抽象成員,該類就不可以被實例化,通常用於強制繼承類必須實現某一成員


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

sealed 修飾符表示密封

用於類時,表示該類不能再被繼承,不能和 abstract 同時使用,因爲這兩個修飾符在含義上互相排斥

用於方法和屬性時,表示該方法或屬性不能再被繼承,必須和 override 關鍵字一起使用,因爲使用 sealed 修飾符的方法或屬性肯定是基類中相應的虛成員

通常用於實現第三方類庫時不想被客戶端繼承,或用於沒有必要再繼承的類以防止濫用繼承造成層次結構體系混亂

恰當的利用 sealed 修飾符也可以提高一定的運行效率,因爲不用考慮繼承類會重寫該成員


7.override 和 overload 的區別?
答:

override 表示重寫,用於繼承類對基類中虛成員的實現

override 表示重載,用於同一個類中同名方法不同參數(包括類型不同或個數不同)的實現

8.什麼是索引指示器?

答:

實現索引指示器(indexer)的類可以象數組那樣使用其實例後的對象

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,通過它我們可以在運行時獲得各種信息,如程序集、模塊、類型、字段、屬性、方法和事件

通過對類型動態實例化後,還可以對其執行操作

一般用於插件式框架程序和設計模式的實現,當然反射是一種手段可以充分發揮其能量來完成你想做的任何事情(前面好象見過一位高人用反射調用一個官方類庫中未說明的函數。。。)


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