尽量采用as操作符而不是旧式C风格做强制类型转换

http://www.cnblogs.com/JiangSoney/archive/2009/08/07/1541488.html

MSDN: https://msdn.microsoft.com/zh-cn/vstudio/cc488006

C#是一种强数据类型语言。(一种总是强制类型定义的语言。如果你有一个整数,如果不显示地进行转换,你不能将其视为
一个字符串。)好的编程习惯提醒我们要尽量避免使用强制转换,但是有的时候我们是无法避免的。

强制转换适用情况:源变量和目标变量兼容。即使这样也存在数据丢失的风险,因为目标变量的类型大小比源变量小或者目
标变量是源变量的一个基类。

在c#里,你有两种方法来实现强制转化:

A、采用as运算符;
B、旧式的C风格“(type)object”。

那么我们应该什么时候采用as运算符,什么时候采用旧式C风格强制类型转换?

先来看一段代码: 

public class Base
{
    public void Read()
    {
        Console.WriteLine("read");
    }
}

public class Derived : Base
{
    public void Write()
    {
        Console.WriteLine("Derived write");
    }
}

public class CTest
{
    public void check_c()    // 采用旧式C风格的强制转换
    {
        object der = new Derived();
        try
        {
            Base bas = (Base)der;
            if (null != bas)
            {
                bas.Read();
            }
            else
            {
                Console.WriteLine("C Cast failed!");
            }
        }
        catch (Exception error)
        {
            Console.WriteLine(error.ToString());
        }
    }
    public void check_as()   // 采用as运算符强制转换
    {
        object obj = new Derived();
        Base bas = obj as Base;
        if (null != bas)
        {
            bas.Read();
        }
        else
        {
            Console.WriteLine("As Cast failed!");
        }

    }
}

  显然,如果要你从check_c()和check_as()方法中选择,你肯定会选后者。因为两者相比较后者具有:

1、 减少了性能开销(try/catch结构的性能开销)
2、 精简了代码
3、 更安全,as转换不会有异常抛出,如果转换失败,也会安全的返回null。

什么情况下使用C风格强制转换

1、用户定义类型转换(http://msdn.microsoft.com/zh-cn/vstudio/ms173105.aspx)。 

public class Wheel
{
    public void Say()
    {
        Console.WriteLine(" I'm a wheel.");
    }
}
public class Car
{
    private Wheel _wheel = new Wheel();
    public void Say()
    {
        Console.WriteLine("I'm a cal with only one wheel.");
    }
    public static implicit operator Wheel(Car itemCar)
    {
        return itemCar._wheel;
    }
}

 注:implicit 关键字用于声明隐式的用户定义类型转换运算符

class Program
{
    static void Main(string[] args)
    {
        object itemCar = new Car();
        Cast(itemCar);
        Console.ReadLine();
    }
    private static void Cast(object obj)
    {
        Car itemCar = obj as Car;
        if (null != itemCar)
        {
            try
            {
                Wheel itemWheel = (Wheel)itemCar;
                if (null != itemWheel)
                {
                    itemWheel.Say();
                }
            }
            catch (Exception error)
            {

            }
        }
    }
}

 在上面的main函数中如果将 Cast(itemCar)改成Wheel itemWheel = itemCar as Wheel将会发生第一种错误:编译可 

以通过,但是转换会失败。另外如果你将main函数改成如下形式,将会发生第二种错误:编译无法通过。

static void Main(string[] args)
{
    Car itemCar = new Car();
    Wheel itemWheel = itemCar as Wheel;
    itemWheel.Say();
    Console.ReadLine();
}

 第一种错误发生的原因是:itemCar被定义为object类型,在编译时将itemCar以System.Object类型生成IL代码,运行 

时法无法将object类型转换成Wheel类型。第二种错误发生的原因是:Car类型和Wheel类型不兼容,既不符合引用转换的要求
,更不符合装箱转换的要求。在Cast(object obj)函数中如果去掉
Car itemCar = obj as Car 同理也会发生第一种错误。

2、 值数据类型的转换,同时采用is运算符来取消可能因转换引发的异常。

object obj = Value();
int i = 0;
if ( obj is int )
i = ( int ) obj;

什么情况下使用as运算法转换

1、 引用转换
A、 隐式引用转换(http://msdn.microsoft.com/zh-cn/library/aa691284(VS.71).aspx);
B、 显示引用转换(http://msdn.microsoft.com/zh-cn/library/aa691291(VS.71).aspx)。
2、 装箱转换(http://msdn.microsoft.com/zh-cn/library/aa691158(VS.71).aspx)。

上面提到在用C风格进行强制类型转换前要采用is运算符进行类型判断,那么is运算符究竟是有什么功能,is运算符和
as运算符有什么区别,我们在使用is运算符时应该注意哪些问题。
is运算符是类型判断运算符,检查对象是否与给定类型兼容,和as运算符一样是安全的,不会发生异常的,与as运算
符不同的是:is运算符不进行类型转换,只返回bool值,表示类型是否兼容。在使用is运算符时注意一下几点:

1、避免冗余。如下面的代码就出现了冗余,实际上is判断是无意义的。 

object obj = Value();
if (itemCar is Car)
{
    Car itemCar = obj as Car;
}

2、在用C风格进行强制类型转换前尽量要采用is运算符进行类型判断。

object obj = Value();
if (itemCar is Car)
{
   Car itemCar = (Car)obj;
}

 总之,在能用as运算符的情况下绝不使用C风格的强制转换。因为as运算符比起C风格盲目的强制转换,as运算符更安 

全,而且在运行时效率更高。

原文地址:https://www.cnblogs.com/gsk99/p/4939867.html