本文總結(jié)C#一些常見的技術(shù)問題,,每一個都是簡短的解釋,,篇幅不大,不斷更新中…
const與readonly
readonly為運行時常量,,const為編譯時常量,。
編譯時常量比運行時常量快,性能好,,但是缺乏靈活性(編譯時常量需要重新編譯應(yīng)用程序),。
編譯時常量(const)僅限于數(shù)值和字符串(基元類型),C#不允許使用new來初始化一個編譯時常量
const修飾的常量默認(rèn)是靜態(tài)的(類型),。
readonly修飾的字段可以在構(gòu)造函數(shù)中被修改,。
使用const較之使用readonly的唯一好處就是性能。
partial關(guān)鍵字
此關(guān)鍵字允許將類,、結(jié)構(gòu)或接口的定義拆分到多個文件中,。
如果類的定義,其內(nèi)容很多,那么分別放在不同的文件中就是一個不錯的選擇。
在File1.cs中
namespace Aiqier { partial class A { int num = 0; void MethodA() {} partial void MethodC(); } }
在File2.cs中
namespace Aiqier { partial class A { void MethodB() {} partial void MethodC() {} } }
sealed關(guān)鍵字
當(dāng)對一個類應(yīng)用 sealed 修飾符時,,此修飾符會阻止其他類從該類繼承,。類似于Java中final關(guān)鍵字,。
new和override
Override關(guān)鍵字主要是提供派生類對基類方法的新實現(xiàn),重寫的基類方法必須和Override的方法具有相同的簽名,。
New關(guān)鍵字主要用來區(qū)別派生類和基類同名方法的選擇問題,,通過隱藏基類方法,達到使編譯器調(diào)用正確的方法的目的,。
也就是說New 關(guān)鍵字在作為修飾符用于向基類成員隱藏繼承成員時,,對于派生類該關(guān)鍵字指示方法是重寫的新方法,但是關(guān)閉了多態(tài)性,。具體調(diào)用的方法為聲明時變量的方法,。
C#中using語句怎么用?
說道using的話,,首先要說的就是.Net中的兩種資源,,也就是托管資源和非托管資源。
托管資源:由CLR管理分配和釋放的資源,,即從CLR里new出來的對象,。
非托管資源:不受CLR管理的對象,如Windows內(nèi)核對象,,文件,,數(shù)據(jù)庫連接,套接字,,COM對象,。
這里要注意,假如說你的類型需要顯式釋放資源,,那么一定要繼承IDispose接口,。
而這個IDispose接口就是為using語法糖提供便利,那種在finall處調(diào)用Dispose函數(shù)的try-catch-finally語句塊,,其實和using語句生成的IL代碼基本上完全一致,。
c#類型轉(zhuǎn)換
值類型
值類型的類型轉(zhuǎn)換,可以理解為用一個類型A的值去初始化一個類型B的變量,。
變寬轉(zhuǎn)換
如果是變寬轉(zhuǎn)換,,那么不會有問題。比如32位的int到64位的int,,或者是int到float,。
變窄轉(zhuǎn)換
如果是變窄轉(zhuǎn)換,那么就可能有問題,。(可能會發(fā)生溢出)
首先,,變窄轉(zhuǎn)換是需要強制類型轉(zhuǎn)換的,不能像隱式轉(zhuǎn)換那樣,,需要在括號中寫入要轉(zhuǎn)換的類型,。
double foo = 3.5; float bar = (float)foo;
溢出
比如short可以存儲0~32767的數(shù)字,,而byte可以存儲的最大值是255,那么你將一個為7的short轉(zhuǎn)換為byte類型,,那么不會有什么問題。但是如果你將一個大于255的short強制類型轉(zhuǎn)換為byte,,那就會有問題,。
byte destinationVar; short sourceVar = 281; destinationVar = (byte)sourceVar; // sourceVar val: 281 / destinationVar: 25
原因是這樣的(源數(shù)據(jù)的最左邊一位丟失了):
281 = 100011001 25 = 000011001 255 = 011111111
這個數(shù)值的例子摘自《c#經(jīng)典入門》
可以使用checked和unchecked關(guān)鍵字檢驗溢出。
checked() unchecked()
默認(rèn)就是unchecked的,,不寫這個關(guān)鍵字也行,。如果是checked,而且發(fā)生了溢出,,就會拋出異常,。
引用類型
引用類型的轉(zhuǎn)換與值類型“看上去有點相反”。
首先要明確的是引用類型轉(zhuǎn)換的是棧中的變量,,而該變量指向的位于堆中的對象不受影響,。
向上轉(zhuǎn)換
將父類的引用指向子類對象是沒什么問題的(多態(tài)的本質(zhì))
向下轉(zhuǎn)換
與值類型的轉(zhuǎn)換類似,引用類型的向下轉(zhuǎn)換也會用到強制類型轉(zhuǎn)換,。
而這種轉(zhuǎn)換并不總是有效(即便是基類到派生類的轉(zhuǎn)換),,轉(zhuǎn)換是否成功,只有在運行的時候才會知道,。
Child child = (Child)father;
最常見的用法是傳遞object對象,,然后在將這個得到的對象轉(zhuǎn)化為要處理的類型,(非泛型集合,,發(fā)送消息機制)
as運算符
強制類型轉(zhuǎn)換出現(xiàn)錯誤會拋出異常,,使用as或is會更加優(yōu)雅。
as運算符用于在兩個引用類型之間轉(zhuǎn)換,,轉(zhuǎn)換失敗后會返回一個null,,并不會拋出異常。
ClassA a = new ClassA(); ClassB b = a as ClassB; if(b != null) { ...... }
無論是as還是is運算符,,都比直接使用強制類型轉(zhuǎn)換要安全,,而且不需要使用異常檢查,只需要判斷結(jié)果是否為空就可以了,。
類型無關(guān)的類型轉(zhuǎn)換
之前提到的引用類型轉(zhuǎn)換,,是指相關(guān)類型之間的轉(zhuǎn)換,比如繼承關(guān)系,,共享接口,。
不相關(guān)的兩個類型,也可以發(fā)生類型轉(zhuǎn)換,,這就要使用到重載運算符,,你需要自己定義內(nèi)部轉(zhuǎn)換的原理,。
需要使用到的重載運算符有: implicit(隱式類型轉(zhuǎn)換) explicit(顯示類型轉(zhuǎn)換)
// 定義ConvClassA到ConvClassB的隱式轉(zhuǎn)換 public class ConvClassA { public static implicit operator ConvClassB(ConvClassA op) { ...... } } // 定義ConvClassB到ConvClassA的顯式轉(zhuǎn)換 public class ConvClassB { public static explicit operator ConvClassA(ConvClassB op) { ...... } }
原文出處: liuaiqi627 的博客 原文鏈接: http://www./study-note/2015/02/27/c-sharp-technical-summary/
|