3.区别对待强制转型与as和is

secondType = (SecondType)firstType; 

强制转型可能意味着两件不同的事情:
(1)FirstType和SecondType彼此依靠转换操作符来完成两个类型之间的转型。
(2)FirstType是SecondType的基类。
类型之间如果存在强制转型,那么它们之间的关系,要么是第一种,要么是第二种,不能同时既是继承的关系,又提供了转型符
第一种情况,代码如下:

    class FirstType  
    {  
        public string Name { get; set; }  
    }  
     
    class SecondType  
    {  
        public string Name { get; set; }  
        public static explicit operator SecondType(FirstType firstType)  
        {  
            SecondType secondType = new SecondType() { Name = "转型自:" + firstType.Name };  
            return secondType;  
        }  
    } 

在这种情况下,如果想转型成功则必须使用强制转型,而不是使用as操作符。

FirstType firstType = new FirstType() { Name = "First Type" };  
SecondType secondType = (SecondType)firstType;         //转型成功  
//secondType = firstType as SecondType;     //编译期转型失败,编译通不过 

复杂一点的应用    :

FirstType firstType = new FirstType() { Name = "First Type" };  
object obj = firstType;  
SecondType secondType = (SecondType) obj; 

这段代码与上段代码相比,仅仅多了一层转型,实际上obj还是firstType,还是转型失败了。这是因为编译器还不够聪明,或者说我们欺骗了编译器。针对(SecondType) obj,编译器首先判断的是:SecondType和object之间有没有继承关系。因为在C#中,所有的类型都是继承自object的,所以上面的代 码编译起来肯定没有问题。但是编译器会自动产生代码来检查obj在运行时是不是SecondType,这样就绕过了转换操作符,所以会转换失败。因此如果类型之间都上溯到了某个共同的基类,那么根据此基类进行的转型(即基类转型为子类本身)应该使用as。子类与子类之间的转型,则应该提供转换操作符,以便进行强制转型。

as操作符永远不会抛出异常,如果类型不匹配(被转换对象的运行时类型既不是所转换的目标类型,也不是其派生类型),或者转型的源对象为null, 那么转型之后的值也为null。

第二种情况,即FirstType是SecondType的基类。在这种情况下,既可以使用强制转型,也可以使用as操作符,代码如下:

    class Program  
    {  
        static void Main(string[] args)  
        {  
            SecondType secondType = new SecondType() { Name = "Second Type" };  
            FirstType firstType1 = (FirstType)secondType;  
            FirstType firstType2 = secondType as FirstType;  
        }  
    }  
     
    class FirstType  
    {  
        public string Name { get; set; }  
    }  
     
    class SecondType : FirstType  
    {  
    } 

但是,即使可以使用强制转型,从效率的角度来看,也建议大家使用as操作符。

再来看一下is操作符:

    static void DoWithSomeType(object obj)  
    {  
        if (obj is SecondType)  
        {  
            SecondType secondType = obj as SecondType;  
            //省略  
        }  
    } 

这个版本显然没有上一个版本的效率高,因为当前这个版本进行了两次类型检测。但是,as操作符有一个问题,即它不能操作基元类型。如果涉及基元类型的算法,就需要通过is转型前的类型来进行判断,以避免转型失败。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值