C 高效程式設計話題集1(每期10話題)

2021-09-22 11:07:58 字數 3244 閱讀 9171

當然,所謂話題,重點在於進行討論,是否是最佳實踐也屬於大家的個人之見。以下觀點若有差錯,盡情蹂躪。

1:string str1 = 「str1」+ 9; 和string str2 = 「str2」+ 9.tostring(); 哪個效率高

可以知道「str1」+ 9,在執行時會完成一次裝箱行為。9.tostring(),沒有發生裝箱行為,int型別的tostring()方法的實際原型為:

public

override

string tostring()

可能有人會問,那是不是原型中的number.formatint32方法會發生裝箱行為呢?實際number.formatint32方法是乙個非託管的方法,原型如下:

[methodimpl(methodimploptions.internalcall), securitycritical]

public

static

extern

string

formatint32(

intvalue,

string

format, numberformatinfo info);

它通過直接操作記憶體來進行int到string的轉換,效率要比裝箱高很多。

所以,答案是:後者

裝箱為什麼會帶來效能損耗,因為它內部發生了太多事情:

1:首先,為值型別在託管堆中分配記憶體。記憶體總量除了值型別本身所分配的記憶體外,還要加上型別物件指標和同步塊索引;

2:值型別的值複製到新分配的堆記憶體;

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:如果不指定列舉的零值,會帶來什麼問題;

static

week 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話題)

近來在小組 c 快速成長團隊 討論了若干話題,有些感覺不錯,特總結與大家分享。當然,所謂話題,重點在於進行討論,是否是最佳實踐也屬於大家的個人之見。以下觀點若有差錯,盡情蹂躪。1 string str1 str1 9 和string str2 str2 9.tostring 哪個效率高 可以知道 s...

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的負數,所有負整數的按位取反是...