近來在小組
c#快速成長團隊
討論了若干話題,有些感覺不錯,特總結與大家分享。
當然,所謂話題,重點在於進行討論,是否是最佳實踐也屬於大家的個人之見。以下觀點若有差錯,盡情蹂躪。
1:string str1 = 「str1」+ 9; 和string str2 = 「str2」+ 9.tostring(); 哪個效率高
可以知道「str1」+ 9,在執行時會完成一次裝箱行為。9.tostring(),沒有發生裝箱行為,int型別的tostring()方法的實際原型為:
publicoverride
string tostring()
可能有人會問,那是不是原型中的number.formatint32方法會發生裝箱行為呢?實際number.formatint32方法是乙個非託管的方法,原型如下:
[methodimpl(methodimploptions.internalcall), securitycritical]public
static
extern
string
formatint32(
intvalue,
string
format, numberformatinfo info);
它通過直接操作記憶體來進行int到string的轉換,效率要比裝箱高很多。
所以,答案是:後者
裝箱為什麼會帶來效能損耗,因為它內部發生了太多事情:
1:首先,為值型別在託管堆中分配記憶體。記憶體總量除了值型別本身所分配的記憶體外,還要加上型別物件指標和同步塊索引;
2:值型別的值複製到新分配的堆記憶體;
3:返回已經成為引用型別的物件的位址;
2:as,is轉型比強制轉型的優勢
優勢在於as,is 不丟擲異常,如果轉型失敗,則返回null
強制轉型則會丟擲異常,導致**必須處理異常,效率低。
值得注意的是,as只能轉型基本型別,對於基本類別如int等的轉型,只能使用強制轉型或is。
3:readonly和const的區別或者說哪個更好
1:const天然就是static的,所以不能用static修飾;readonly無此限制;
2:const只能修飾基元型別;readonly無此限制;
3:const是編譯期常量;readonly為執行期常量,其初始值除了在初始化器還可以在型別的建構函式中設定;
4:const經編譯後,以實際值代替了變數(可檢視il驗證),效率顯然要高一些,可用到關鍵演算法中,除此之外,與readonly比沒有任何優勢。
4:初始化器和構造器的異同
初始化器實際是語法糖,經編譯後,它在建構函式的最開始執行。也就是說,初始化器可以理解為建構函式的一部分。
5:列舉在使用中的注意事項
1:如果不指定列舉的零值,會帶來什麼問題;
staticweek week;
static
void
main(
string
args)
即使未給week賦值,也會列印出零值。
2:如果為列舉中的元素指定了相同的值,又會帶來什麼問題。
會導致相等型比較的時候出現與預期不符的結果
3:建議不給列舉顯式指定值,但是如果列舉用於位運算則要為其元素指定2的指數冪值。
6:為什麼linq語句都要開始於from而不是select
顯而易見的原因是為了智慧型感知,要讓他在輸入linq查詢的時候起作用,from子句就必須在最前面;如:
var allcustomers = from customer in db.customers
select new ;
7:dynamic可以用它來簡化反射。
使用反射,呼叫方**:
dynamicsample dynamicsample=new
dynamicsample();
var addmethod
=typeof
(dynamicsample).getmethod(
"add");
intre =(
int)addmethod.invoke(dynamicsample,
newobject
); 在使用dynamic後,我們的**看上去更簡潔了,並且在可控的範圍內減少了一次拆箱的機會:
dynamic dynamicsample2=new
dynamicsample();
intre2
=dynamicsample2.add(1,
2);
8:foreach不能替代for的原因
1: 首先,對集合的每次增刪操作(是不是全部集合?不得而知,但是起碼是絕大部分集合),都會讓集合的version欄位+1,foreach採用的是迭代器模式,每次迭代的時候都要判斷version是不是保持一致,如果不一致,則丟擲異常。而for沒有這方面的限制。所以,採用
list<
int>
list
=new
list
<
int>
() ;
foreach
(int
item
inlist)
會丟擲異常,而改為for則不會。這是for不能被foreach取代叼的最重要原因。
2:foreach預設呼叫集合的迭代器的dispose方法,如果該迭代器繼承了idispose方法的話。
9:區別icomparable和icomparer
前者icomparable為類提供預設的比較器,而icomparer可以為集合類提供更多的比較器。具體檢視
10:linq和比較器及迭代器優缺點比較
要進行排序和比較,傳統的方式,存在兩個問題:
1:可擴充套件性太低,如果存在新的排序要求,就得實現新的比較器;
2:對**的侵入性太高,為型別繼承了介面,增加了新的方法;
可參見博文的討論:
在我們自己的**中強烈建議你利用linq帶來便捷性,但我們仍需掌握比較器、迭代器、索引器的原理,以便我們更好地理解linq的思想,寫出更加高質量的**。
C 高效程式設計話題集1(每期10話題)
近來在小組 c 快速成長團隊 討論了若干話題,有些感覺不錯,特總結與大家分享。當然,所謂話題,重點在於進行討論,是否是最佳實踐也屬於大家的個人之見。以下觀點若有差錯,盡情蹂躪。1 string str1 str1 9 和string str2 str2 9.tostring 哪個效率高 可以知道 s...
C 高效程式設計話題集1(每期10話題)
當然,所謂話題,重點在於進行討論,是否是最佳實踐也屬於大家的個人之見。以下觀點若有差錯,盡情蹂躪。1 string str1 str1 9 和string str2 str2 9.tostring 哪個效率高 可以知道 str1 9,在執行時會完成一次裝箱行為。9.tostring 沒有發生裝箱行為...
C語言程式設計錯題集(1)
假設有變數定義如下 int a,k 則以下哪條語句不能確保將變數k的值變為0 a.k a a 1 b.k k c.k k a k a d.k k k 正確答案 c 解析 1 對a選項,表示按位取反,運算物件是二進位制資料,1變0,0變1。所有正整數的按位取反是其本身 1的負數,所有負整數的按位取反是...