本节内容不太复杂,主要是介绍类的实例创建过程,以及类型之间相互转换的知识。
CLR要求用new操作符创建对象,这个操作符在编译时产生的IL指令为newobj。例如:
Student XiaoJing=new Student(“XiaoJing”,”1986”);
那么在创建过程中,究竟发生了什么事呢?
C#中,向基类转换直接隐式进行就可以;向派生类转换则需要显示进行,因为有可能会失败。在运行时,CLR会检查转型操作以确保是将对象转化为它的实际类型或者它的基类型。
class Animal { }
class Dog : Animal { }
Animal a=new Dog();
Dog b=(Dog)a; //显示转换,基类向派生类
Animal a=new Dog(); //隐式转换,派生类向基类
IS和AS?
要想检查对象和类是否兼容,有两种方式:Is和As。
If(a is Dog)//第一次转换
{
Dog g=a;//第二次转换
………
}
Dog g=a as Dog;//转换一次,失败则为null
If(g!=null) {…}
下面来看一个类型转换的例子,看每行代码在编译和运行时是否能够正确通过?如果你都答对了,那么本节课的理解就及格了。
还是上面的两个类,Animal和Dog,主要考察类型转换的知识。
代码 |
正确 |
编译错误 |
运行错误 |
class Program |
|||
{ |
|||
static void Main(string[] args) |
|||
{ |
|||
Object o1 = new Object(); |
√ |
||
Object o2 = new Animal(); |
√ |
||
Object o3 = new Dog(); |
√ |
||
Object o4 = o3; |
√ |
||
Animal Animal1 = new Animal(); |
√ |
||
Animal Animal2 = new Dog(); |
√ |
||
Dog Dog1 = new Dog(); |
√ |
||
Animal Animal3 = new Object(); |
√① |
||
Dog Dog2 = new Object(); |
√② |
||
Animal Animal4 = Dog1; |
√ |
||
Dog Dog3 = Animal2; |
√③ |
||
Dog Dog4 = (Dog)Dog1; |
√ |
||
Dog Dog5 = (Dog)Animal2; |
√ |
||
√④ |
|||
Animal Animal5 = (Animal)o1; |
√⑤ |
||
Animal Animal6 = (Dog)Animal2; |
√ |
||
} |
|||
} |
错误点解析:
① Animal Animal3 = new Object();
基类向派生类转换应该显示进行,所以编译就报错了。实际上就算改成显示转型也会发生运行时错误,因为对象类型不兼容。可以尝试改成Animal Animal3 = (Animal)o2;
② Dog Dog2 = new Object();
理由同①,正解为Dog Dog2 =(Dog)o3;
③ Dog Dog3 = Animal2;
理由同①,正解为Dog Dog3 =(Dog) Animal2;
④ Dog Dog6 = (Dog)Animal1
基类向派生类显示转型,语法上没有错误因此编译通过。但在运行时,CLR会检查转型操作以确保是将对象转化为它的实际类型或者它的基类型。 而Animal1对象是Animal类型而非Dog类型,因此转型时发生失败。如果添加一句Animal1=new Dog();再执行该转型则会成功。
⑤ Animal Animal5 = (Animal)o1;
理由同④。这里不再赘述了。
文章出处:跟小静读CLR via C#