C# 基礎技術問題總結

發表於2015-03-25

本文總結C#一些常見的技術問題,每一個都是簡短的解釋,篇幅不大,不斷更新中…

const與readonly

readonly為執行時常量,const為編譯時常量。

編譯時常量比執行時常量快,效能好,但是缺乏靈活性(編譯時常量需要重新編譯應用程式)。

編譯時常量(const)僅限於數值和字串(基元型別),C#不允許使用new來初始化一個編譯時常量

const修飾的常量預設是靜態的(型別)。

readonly修飾的欄位可以在建構函式中被修改。

使用const較之使用readonly的唯一好處就是效能。

partial關鍵字

此關鍵字允許將類、結構或介面的定義拆分到多個檔案中。

如果類的定義,其內容很多,那麼分別放在不同的檔案中就是一個不錯的選擇。

在File1.cs中

在File2.cs中

sealed關鍵字

當對一個類應用 sealed 修飾符時,此修飾符會阻止其他類從該類繼承。類似於Java中final關鍵字。

new和override

Override關鍵字主要是提供派生類對基類方法的新實現,重寫的基類方法必須和Override的方法具有相同的簽名。

New關鍵字主要用來區別派生類和基類同名方法的選擇問題,通過隱藏基類方法,達到使編譯器呼叫正確的方法的目的。

也就是說New 關鍵字在作為修飾符用於向基類成員隱藏繼承成員時,對於派生類該關鍵字指示方法是重寫的新方法,但是關閉了多型性。具體呼叫的方法為宣告時變數的方法。

C#中using語句怎麼用?

說道using的話,首先要說的就是.Net中的兩種資源,也就是託管資源和非託管資源。

託管資源:由CLR管理分配和釋放的資源,即從CLR裡new出來的物件。

非託管資源:不受CLR管理的物件,如Windows核心物件,檔案,資料庫連線,套接字,COM物件。

這裡要注意,假如說你的型別需要顯式釋放資源,那麼一定要繼承IDispose介面。

而這個IDispose介面就是為using語法糖提供便利,那種在finall處呼叫Dispose函式的try-catch-finally語句塊,其實和using語句生成的IL程式碼基本上完全一致。

c#型別轉換

值型別

值型別的型別轉換,可以理解為用一個型別A的值去初始化一個型別B的變數。

變寬轉換

如果是變寬轉換,那麼不會有問題。比如32位的int到64位的int,或者是int到float。

變窄轉換

如果是變窄轉換,那麼就可能有問題。(可能會發生溢位)

首先,變窄轉換是需要強制型別轉換的,不能像隱式轉換那樣,需要在括號中寫入要轉換的型別。

溢位

比如short可以儲存0~32767的數字,而byte可以儲存的最大值是255,那麼你將一個為7的short轉換為byte型別,那麼不會有什麼問題。但是如果你將一個大於255的short強制型別轉換為byte,那就會有問題。

原因是這樣的(源資料的最左邊一位丟失了):

這個數值的例子摘自《c#經典入門》

可以使用checked和unchecked關鍵字檢驗溢位。

預設就是unchecked的,不寫這個關鍵字也行。如果是checked,而且發生了溢位,就會丟擲異常。

引用型別

引用型別的轉換與值型別“看上去有點相反”。

首先要明確的是引用型別轉換的是棧中的變數,而該變數指向的位於堆中的物件不受影響。

向上轉換

將父類的引用指向子類物件是沒什麼問題的(多型的本質)

向下轉換

與值型別的轉換類似,引用型別的向下轉換也會用到強制型別轉換。

而這種轉換並不總是有效(即便是基類到派生類的轉換),轉換是否成功,只有在執行的時候才會知道。

最常見的用法是傳遞object物件,然後在將這個得到的物件轉化為要處理的型別,(非泛型集合,傳送訊息機制)

as運算子

強制型別轉換出現錯誤會丟擲異常,使用asis會更加優雅。

as運算子用於在兩個引用型別之間轉換,轉換失敗後會返回一個null,並不會丟擲異常。

無論是as還是is運算子,都比直接使用強制型別轉換要安全,而且不需要使用異常檢查,只需要判斷結果是否為空就可以了。

型別無關的型別轉換

之前提到的引用型別轉換,是指相關型別之間的轉換,比如繼承關係,共享介面。

不相關的兩個型別,也可以發生型別轉換,這就要使用到過載運算子,你需要自己定義內部轉換的原理。

需要使用到的過載運算子有: implicit(隱式型別轉換) explicit(顯示型別轉換)

相關文章