关于C#的类型转换

    前段时间宁波社区讨论了类型转换是用as关键字好还是用()好的问题,当时我轻易地相信了一片转载的文章的观点(http://hi.baidu.com/salangane0512/blog/item/24a7448b49011d17c8fc7aa9.html),认为用as比用()好。今天偶尔试验了一下,其实事情不是那样的,我当时的不严谨导致犯了一个小小的经验主义错误。

    看下面的代码:
   
    
    
//类型定义
    public interface I
    {
        
string Name { getset; }
    }

    
public class A : I
    {
        
public string Name { getset; }
    }

    
public class B : A
    {
        
public int Key;


        
public static explicit operator string(B operand)
        {
            
return operand.Name;
        }
    }


    
    
//方法调用
     private void button1_Click(object sender, EventArgs e)
    {
        B b 
= new B();
        A a1, a2;

        a1 
= (A)b;
        a2 
= b as A;

        
string h = (string)b;
    }

    对应调用方法的IL代码:
.method private hidebysig instance void button1_Click(object sender, class [mscorlib]System.EventArgs e) cil managed
{
    .maxstack 
1
    .locals init (
        [
0class WindowsFormsApplication15.B b,
        [
1class WindowsFormsApplication15.A a1,
        [
2class WindowsFormsApplication15.A a2,
        [
3string h)
    L_0000: nop 
    L_0001: newobj instance 
void WindowsFormsApplication15.B::.ctor()
    L_0006: stloc.
0 
    L_0007: ldloc.
0 
    L_0008: stloc.
1 
    L_0009: ldloc.
0 
    L_000a: stloc.
2 
    L_000b: ldloc.
0 
    L_000c: call 
string WindowsFormsApplication15.B::op_Explicit(class WindowsFormsApplication15.B)
    L_0011: stloc.
3 
    L_0012: ret 
}


 

    这下很清楚了,()和as在做类型转换的时候都是一样处理的,根本不存在所谓那个性能好那个性能坏的问题,完全是受个人习惯影响的。

    使用as唯一的好处是可以分清你是在做基于基类和接口的类型转换还是使用操作符重载机制(CLR编译器层处理)的类型转换(后一种本质上就是调用一种方法!!)。比如例子中的: string h = (string) b; 。这是使用as替代()操作符的唯一好处,而不是那篇文章中长篇大论讲的那样。

    判断类型用is,转换的话最好用as,只是因为这样清楚一些。

    大家在工作交流中经常会犯一些不严谨的错误,我在此先作自我批评,希望大家平时多加注意和改正。
posted @ 2008-07-05 12:12 王弈博 阅读(194) 评论(4)  编辑 收藏 所属分类: .NET框架与语言

  回复  引用    
#1楼 2008-07-05 18:28 | James_cn [未注册用户]
as 比 () 好的原因是在转换错误的时候不会引发异常,
异常很占用资源,所以在.net 2.0中也提供了TryParse这样的方法
  回复  引用  查看    
#2楼 [楼主]2008-07-05 18:56 | 王弈博      
--引用--------------------------------------------------
James_cn: as 比 () 好的原因是在转换错误的时候不会引发异常,
异常很占用资源,所以在.net 2.0中也提供了TryParse这样的方法
--------------------------------------------------------


恩,其实是这样的,类型转换实际上分两种:第一种就是做基于基类和接口的类型转换,也就是继承类之间的转化,这种情况无论是用as还是(),CLR编译器是会作检查的,要么就通不过编译要么就一定不会出错,而且编译出的IL代码是一模一样的。

第二种情况就像我上面例子写的那个显式转换的例子,那其实是一个方法调用,写成()的坏处在于你总会误认为它是像第一种情况那样的类型转换,自然会在运算时抛出异常的。你说的会抛出异常的情况一定是这种情况。

你可以详细的试一下。

所以严谨一点的话,写成as好,因为一看就确认是在做继承类(接口)之间的转换,写成()的话,就有点不清楚了,仅此而已。
  回复  引用  查看    
#3楼 [楼主]2008-07-05 19:05 | 王弈博      
谢谢James_cn 的评论,太冷清了,呵呵
  回复  引用  查看    
#4楼 2008-07-09 08:37 | 鹰击长空      
使用as是一种防御性编程,可以通过a2 = b as A;if(a2!=null){}避免异常

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-07-05 12:16 编辑过


相关链接: