C#高效編程話題集1(每期10話題)

 

C#高效編程話題集1(每期10話題)

2011-03-02 09:02 by 陸敏技, 3364 visits, 網摘收藏編輯
近來在小組 C#快速成長團隊  討論了若干話題,有些感受不錯,特總結與你們分享。
固然,所謂話題,重點在於進行討論,是不是最佳實踐也屬於你們的我的之見。如下觀點如有差錯,盡情蹂躪。
1:String str1 = 「str1」+ 9; 和String str2 = 「str2」+ 9.ToString(); 哪一個效率高
能夠知道「str1」+ 9,在運行時會完成一次裝箱行爲。9.ToString(),沒有發生裝箱行爲,Int類型的ToString()方法的實際原型爲:
       
       
       
       
public override String ToString() {
return Number.FormatInt32(m_value, null , NumberFormatInfo.CurrentInfo);
}
可能有人會問,那是否是原型中的Number.FormatInt32方法會發生裝箱行爲呢?實際Number.FormatInt32方法是一個非託管的方法,原型以下:
       
       
       
       
[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
public static extern string FormatInt32( int value, string format, NumberFormatInfo info);
它經過直接操做內存來進行int到string的轉換,效率要比裝箱高不少。
因此,答案是:後者
裝箱爲何會帶來性能損耗,由於它內部發生了太多事情:
1:首先,爲值類型在託管堆中分配內存。內存總量除了值類型自己所分配的內存外,還要加上類型對象指針和同步塊索引;
2:值類型的值複製到新分配的堆內存;
3:返回已經成爲引用類型的對象的地址;

2:as,is轉型比強制轉型的優點

優點在於as,is 不拋出異常,若是轉型失敗,則返回nullhtml

強制轉型則會拋出異常,致使代碼必須處理異常,效率低。算法

值得注意的是,as只能轉型基本類型,對於基本類別如int等的轉型,只能使用強制轉型或is。編程


3:readonly和const的區別或者說哪一個更好
ide

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)
{
Console.WriteLine(week);
}

即便未給week賦值,也會打印出零值。

2:若是爲枚舉中的元素指定了相同的值,又會帶來什麼問題。post

會致使相等型比較的時候出現與預期不符的結果
3:建議不給枚舉顯式指定值,可是若是枚舉用於位運算則要爲其元素指定2的指數冪值。

6:爲何LINQ語句都要開始於from而不是select
顯而易見的緣由是爲了智能感知,要讓他在輸入LINQ查詢的時候起做用,from子句就必須在最前面;如:
var AllCustomers = from Customer in db.Customers 
select new { Customer.ContactName, Customer.Country }; 

7:dynamic能夠用它來簡化反射。
使用反射,調用方代碼:
      
      
      
      
DynamicSample dynamicSample = new DynamicSample();
var addMethod
= typeof (DynamicSample).GetMethod( " Add " );
int re = ( int )addMethod.Invoke(dynamicSample, new object [] { 1 , 2 });

在使用dynamic後,咱們的代碼看上去更簡潔了,而且在可控的範圍內減小了一次拆箱的機會:
      
      
      
      
dynamic dynamicSample2 = new DynamicSample();
int re2 = dynamicSample2.Add( 1 , 2 );
 

8:foreach不能替代for的緣由
1: 首先,對集合的每次增刪操做(是否是所有集合?不得而知,可是起碼是絕大部分集合),都會讓集合的version字段+1,foreach採用的是迭代器模式,每次迭代的時候都要判斷version是否是保持一致,若是不一致,則拋出異常。而for沒有這方面的限制。因此,採用

      
      
      
      
List < int > list = new List < int > () { 0 , 1 , 2 , 3 };
foreach ( int item in list)
{
list.Remove(item);
Console.WriteLine(item.ToString());
}

會拋出異常,而改成for則不會。這是for不能被foreach取代叼的最重要緣由。

2:foreach默認調用集合的迭代器的Dispose方法,若是該迭代器繼承了IDispose方法的話。

9:區別IComparable<T>和IComparer<T>
前者IComparable<T>爲類提供默認的比較器,而IComparer<T>能夠爲集合類提供更多的比較器。具體查看 http://www.cnblogs.com/luminji/archive/2010/09/30/1839038.html
 
 
10:LINQ和比較器及迭代器優缺點比較
要進行排序和比較,傳統的方式,存在兩個問題:
1:可擴展性過低,若是存在新的排序要求,就得實現新的比較器;
2:對代碼的侵入性過高,爲類型繼承了接口,增長了新的方法;
可參見博文的討論: http://www.cnblogs.com/luminji/archive/2011/02/17/1956723.html。 在咱們本身的代碼中強烈建議你利用LINQ帶來便捷性,但咱們仍需掌握比較器、迭代器、索引器的原理,以便咱們更好地理解LINQ的思想,寫出更加高質量的代碼。
相關文章
相關標籤/搜索