成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C#類型轉化的五點心得

開發 后端
C#是一門強類型的語言。大家都寫過很多以System.Object類型為參數的函數,在這些函數內部,我們經常要吧那些參數向下轉型為其他類型。本文將介紹C#類型轉化的五點心得。

對于這種C#類型轉化我們通常用兩種選擇:使用as操作符,或者使用強制轉型。當然還有一個做法是先用is測試轉換是否可行,然后再用as或者強制轉換。

本文主要給大家提醒一些使用C#類型轉化時需要注意的地方,或許你更想弄清楚as和強制轉換的區別和使用場景,不用著急,看完,本文你自己就知道答案了,那么上面提到的兩種C#類型轉化我們需要注意哪些呢?

1、as和is操作符都不執行任何用戶自定義的轉換。

2、對于強制轉換,引用為空將會轉換出錯。

3、強制轉換任意類型和自定義轉換兩種情況的IL代碼展示有區別。

4、用戶自定義轉換只作用于對象的編譯時類型。

5、as操作符不能應用于值類型。

6、foreach循環語句中使用強制類型轉型。

下面我們逐一進行介紹說明:

1,我們先來看錯誤代碼示例:

  1. classA  
  2. {  
  3.  
  4. }  
  5. classC  
  6. {  
  7. publicstaticimplicitoperatorA(Ct)  
  8. {  
  9. returnnewA();  
  10. }  
  11. }  
  12. classProgram  
  13. {  
  14. staticvoidMain(string[]args)  
  15. {  
  16. objecto=Factory.GetObject();  
  17. //o為一個C類型:  
  18. Aa=oasA;//轉型失敗,o的類型不是A  
  19. }  

代碼已經很明顯,我們不可以因為定義了C到A的強制轉換,就使用as,對應用戶自定義轉換,我們只可以使用(A)o轉換,其實自定義轉換和自定義操作=、+、-、"、%等操作符是一樣的機理,這樣你就明白為什么用as不可以使用自定義轉換了。


2,還是看一個錯誤示例:

  1. classA  
  2. {  
  3.  
  4. }  
  5. classB:A  
  6. {  
  7.  
  8. }  
  9. classProgram  
  10. {  
  11. staticvoidMain(string[]args)  
  12. {  
  13. Bb;  
  14. Aa=(A)b;  
  15. }  
  16. }  
  17. 問題不用多言,as可以解決這個問題。  
  18.  
  19.  
  20. 3,看一個示例:  
  21.  
  22. classA  
  23. {  
  24.  
  25. }  
  26. classC  
  27. {  
  28. publicstaticimplicitoperatorA(Ct)  
  29. {  
  30. returnnewA();  
  31. }  
  32. }  
  33. classB:A  
  34. {  
  35.  
  36. }  
  37. classProgram  
  38. {  
  39. staticvoidMain(string[]args)  
  40. {  
  41. Aa=newB();  
  42. Bb=(B)a;  
  43. Cc=newC();  
  44. a=(A)c;  
  45. }  
  46. }  
  47. 對于Bb=(B)a;的IL代碼如下:  
  48.  
  49. IL_0008:castclassConsoleApplication1.B  
  50.  
  51. 對于a=(A)c;的IL代碼如下:  
  52.  
  53. IL_0015:callclassConsoleApplication1.AConsoleApplication1.C::op_Implicit(classConsoleApplication1.C)  
  54. 區別大家已經看到了,要說真正認識區別那么我們要繼續談“4、用戶自定義轉換只作用于對象的編譯時類型。"  
  55.  
  56. 4,看一個示例:  
  57.  
  58. classA  
  59. {  
  60.  
  61. }  
  62. classC  
  63. {  
  64. publicstaticimplicitoperatorA(Ct)  
  65. {  
  66. returnnewA();  
  67. }  
  68. }  
  69. classB:A  
  70. {  
  71.  
  72. }  
  73. classProgram  
  74. {  
  75. staticvoidMain(string[]args)  
  76. {  
  77. Aa=newB();  
  78. Bb=(B)a;  
  79. objectc=newC();  
  80. a=(A)c;//編譯通過,運行失敗!  
  81. }  

也許你從來沒想過a=(A)c;編譯會成功,運行會出錯在這句,畢竟我們有一個顯示類型C到類型A的轉換操作,我們看看IL代碼即可找到答案,

  1. .methodprivatehidebysigstaticvoidMain(string[]args)cilmanaged  
  2. {  
  3. .entrypoint  
  4. //Codesize28(0x1c)  
  5. .maxstack1  
  6. .localsinit([0]classConsoleApplication1.Aa,  
  7. [1]classConsoleApplication1.Bb,  
  8. [2]objectc)  
  9. IL_0000:nop  
  10. IL_0001:newobjinstancevoidConsoleApplication1.B::.ctor()  
  11. IL_0006:stloc.0  
  12. IL_0007:ldloc.0  
  13. IL_0008:castclassConsoleApplication1.B  
  14. IL_000d:stloc.1  
  15. IL_000e:newobjinstancevoidConsoleApplication1.C::.ctor()  
  16. IL_0013:stloc.2  
  17. IL_0014:ldloc.2  
  18. IL_0015:castclassConsoleApplication1.A  
  19. IL_001a:stloc.0  
  20. IL_001b:ret  
  21. }//endofmethodProgram::Main 

大家注意看IL_0015:castclassConsoleApplication1.A這句,這句說明自定義轉換在編譯時刻進行,也許你要問為什么不是第3條的:

IL_0015:callclassConsoleApplication1.AConsoleApplication1.C::op_Implicit(classConsoleApplication1.C)

因為objectc,c被定義為Object類型,那么強制轉換在編譯時刻去Object找是否存在自定義轉換操作(注意,()轉型時編譯器優先考慮自定義轉換,找不到才進行castclass),當然Object沒有自定義轉換為A的操作,那么就使用普通的強制轉換castclass。好了現在我們知道了用戶自定義轉換只作用于對象的編譯時類型,而普通的Bb=(B)a;強制轉換可以作用到運行時刻。那么上面的錯誤如何去掉呢?對應代碼修改為:

  1. objectc=newC();  
  2. Ccc=casC;  
  3. a=(A)cc; 

現在運行正常通過,好了我們再次查看IL代碼

IL_001c:callclassConsoleApplication1.AConsoleApplication1.C::op_Implicit(classConsoleApplication1.C)

到這大家對3和4點的認識應該很清楚了吧。

5、as操作符不能應用于值類型————省略!,鑒于這個點很簡單,本人就不提供示例了,大家有興趣可以自己試驗下。

6、看代碼示例:(以下代碼摘自《EffectiveC#中文版改善C#程序的50中方法》——23頁)

  1. publicvoidUseCollection(IEnumerabletheCollection)  
  2. {  
  3. foreach(MyTypetintheCollection)  
  4. t.DoStuff();  
  5. }  
  6.  
  7. //上面代碼等同于:  
  8.  
  9. publicvoidUseCollection(IEnumerabletheCollection)  
  10. {  
  11. IEnumeratorit=hteCollection.GetEnumerator();  
  12. while(it.MoveNext())  
  13. {  
  14. MyTypet=(MyType)it.Current;  
  15. t.DoStuff();  
  16. }  

通過查看IL代碼我們可以確認foreach語句的轉換是使用的強制轉換操作,那么為什么呢?之所以使用強制轉型,是因為foreach語句需要同時支持值類型和引用類型,這側面說明我們的第5點as不支持值類型。

好了,5點C#類型轉化說明已經解釋完了,你現在還想問as和強制轉換的區別和使用場景么?,歡迎提出批評、指正錯誤。

【編輯推薦】

  1. C#讀取文件夾中的文件操作淺析
  2. C#讀取文件夾下面的全部文件的實現
  3. C#讀取文件內容另存的實現
  4. C#讀取文件高效方法淺析
  5. C#讀文本文件的冰山一角
責任編輯:彭凡 來源: xueit.com
相關推薦

2017-06-28 15:24:10

大數據數據分析心得

2017-07-05 18:10:23

大數據分析思路心得

2009-06-02 11:25:22

HibernateJPA映射

2009-08-12 18:28:49

C#強制類型轉化

2009-08-18 10:59:46

C#枚舉類型

2011-10-25 10:51:08

私有云虛擬化公有云

2009-06-25 13:59:59

java認證FileFilter

2013-09-11 16:29:02

產品經理產品運營

2009-08-25 13:57:09

C#泛型集合類型

2009-08-18 13:06:17

C#枚舉類型

2009-08-25 16:32:24

C#語言

2009-08-26 17:22:09

C#語言

2013-08-13 14:11:23

2009-08-10 17:25:58

C#匿名類型

2009-09-04 13:37:44

C#貨幣格式

2009-08-13 13:03:52

C#結構體數組

2009-08-13 13:17:10

C#結構體數組

2009-08-26 10:34:15

C#類型C#變量

2009-08-03 13:34:06

自定義C#控件

2011-01-04 09:34:23

LambdaC#
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91麻豆精品国产91久久久更新资源速度超快 | 特级丰满少妇一级aaaa爱毛片 | 国产精品久久福利 | 午夜影院视频在线观看 | 久久人人网 | 日韩精品一区二区三区中文在线 | 狠狠草视频 | 亚洲欧美在线观看视频 | 亚洲人久久 | 成人午夜视频在线观看 | 午夜影院在线视频 | 二区视频 | 国产精品自产av一区二区三区 | 欧美日韩国产高清 | 特黄小视频 | 日韩国产一区二区三区 | 国产精品福利一区二区三区 | 日韩在线一区二区 | 在线一级片 | 免费av在线 | 欧美日韩精品一区 | 久久久www成人免费无遮挡大片 | 国产视频精品在线观看 | 久久久久欧美 | 午夜av毛片 | 国产成人一区二区三区 | 羞羞的视频在线看 | 国产美女自拍视频 | 午夜极品| 成人亚洲综合 | 欧美国产一区二区 | www.v888av.com| 日韩在线中文字幕 | 91麻豆精品国产91久久久久久 | 成人免费激情视频 | 日韩天堂av | www国产成人免费观看视频,深夜成人网 | 欧美a区 | 中文字幕第十一页 | 日本久久久一区二区三区 | 亚洲一区二区不卡在线观看 |