C#类型转化的五点心得

对于这种C#类型转化我们通常用两种选择:使用as操作符,或者使用强制转型。当然还有一个做法是先用is测试转换是否可行,然后再用as或者强制转换。

创新互联主营柳河网站建设的网络公司,主营网站建设方案,重庆APP开发公司,柳河h5成都微信小程序搭建,柳河网站营销推广欢迎柳河等地区企业咨询

本文主要给大家提醒一些使用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和强制转换的区别和使用场景么?,欢迎提出批评、指正错误。

本文名称:C#类型转化的五点心得
本文URL:http://www.gawzjz.com/qtweb/news31/163831.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联