VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#教程 >
  • C#教程之C#教程之C# 类型转换

本站最新发布   C#从入门到精通
试听地址  
https://www.xin3721.com/eschool/CSharpxin3721/

第一部分:

如果从Java转到C#的同学在遇到类型转换的时候,肯定第一反应就是使用强制类型转换。

不过在C#里面两个比较神奇的东西,首先我们说的是as:

当我们直接使用强制类型转换的时候:

Object obj = new NewTpe();
NewType newObj = (NewType)obj;

在这个过程中是不安全的,还要使用try catch来进行保护。

这样一来,代码就变成了:

Object obj1 = new NewType();
NewType newValue = null
try
{
newValue = NewTypeobj1
}
catch Exception err
{
MessageBox.Showerr.Message;
}

不过在C#中这样的方法比较低效,这里推荐使用关键字as:

Object obj1 = new NewType();
NewType newValue = obj1 as NewType

安全性:

as操作符不会做过的转换操作,当需要转化对象的类型属于转换目标类型或者转换目标类型的派生类型时,那么此转换操作才能成功,而且并不产生新的对象【当不成功的时候,会返回null】。因此用as进行类型转换是安全的。

效率:

当用as操作符进行类型转换的时候,首先判断当前对象的类型,当类型满足要求后才进行转换,而传统的类型转换方式,是用当前对象直接去转换,而且为了保护转换成功,要加上try-catch,所以,相对来说,as效率高点。

需要注意的是,不管是传统的还是as操作符进行类型转换之后,在使用之前,需要进行判断转换是否成功,如下:

ifnewValue = null
{
//Work with the object named “newValue“
}

不过as也要注意以下两点:

1.不能在类型之间进行转化,会出现编译错误(相互有继承关系除外):

NewType newValue = new NewType(); 
NewTYpe1 newValue1 = newValue as NewTYpe1;//错误

2.不能用在值类型数据,也会出现编译错误:

Object obj1 = 11;
int nValue = obj1 as int;//错误

对于1.,可以用传统的类型转换方式完成:

NewTypeOne newTestOne = new NewTypeOne();
NewTypeTwo newTestTwo = NewTypeTwonewTestOne;

要想使上面的操作正确完成,在原有类型中增加类型转换操作符函数,即需要完成类似如下的代码:

public class NewTypeOne
{
    public static explicit operator NewTypeTwo( NewTypeOne obj1)
    {
        //Convert object into new type
    }
}

对于2,在C#中可以使用is操作符,再加上老式的类型转换操作,就可以安全完成转换,要完成如上操作,正确的写法如下:

Object obj1 = 11
ifobjTest is int 
{
    int nValue = intobj1
}

在C#中提供的很好的类型转换方式总结为:

Object => 已知引用类型——使用as操作符完成;

Object => 已知值类型——先使用is操作符来进行判断,再用类型强转换方式进行转换;

已知引用类型之间转换——首先需要相应类型提供转换函数,再用类型强转换方式进行转换;

已知值类型之间转换——最好使用系统提供的Conver类所涉及的静态方法。

 

第二部分:

让我们来说说is:

Is:检查对象是否与给定的类型兼容。例如,下面的代码可以确定MyObject类型的一个实例,或者对象是否从MyObject派生的一个类型:

if(obj is MyObject){}

如果所提供的表达式非空,并且所提供的对象可以强制转换为所提供的类型而不会导致引发异常,则 is 表达式的计算结果将是 true。

如果已知表达式始终是true或始终是false,则is关键字将导致编译时警告,但是通常在运行时才计算类型兼容性。

Object myObject = new Object(); 
Boolean b1 = (myObject is Object);      //true.  
Boolean b2 = (myObject is Employee);    //false.

如果对象引用是null,is运算符总是返回false,因为没有可检查其类型的对象。

is运算符通常像下面这样使用:

if (myObject is Employee)
{
     Employee myEmployee = (Employee)myObject;
}

在这段代码中,CLR实际会检查两次对象的类型。is运算符首先核实myObject是否兼容于Employee类型。如果是,那么在if语句内部执行转换型,CLR会再次核实myObject是否引用一个Employee。CLR的类型检查增加了安全性,但这样对性能造成一定影响。这是因为CLR首先必须判断变量(myObject)引用的对象的实际类型。然后,CLR必须遍历继承层次结构,用每个基类型去核对指定的类型(Employee)。由于这是一个相当常用的编程模式,所以C#专门提供了as运算符,目的就是简化这种代码写法,同时提升性能。

我们可以使用as 来提高性能:

    Employee myEmployee = myObject as Employee;
    if (myEmployee != null)
    { }

在这段代码中,CLR核实myObject是否兼容于Employee类型;如果是,as会返回对同一个对象的一个非null的引用。如果myObject不兼容于Employee类型,as运算符会返回null。

as运算符的工作方式与强制类型转换一样,只是它永远不会抛出一个异常。相反,如果对象不能转换,结果就是null。所以,正确的做法是检查最终生成的一引用是否为null。如果企图直接使用最终生成的引用,会抛出一个System.NullReferenceException异常。

    Object o = new Object();        //新建一个Object对象。

    Employee e = o as Employee;     //将o转型为一个Employee
    e.ToString();                   //访问e会抛出一个NullReferenceException异常

 

参考资料:

C#中as用法 - **sunshining** - 博客园

相关教程