类型安全应该算是CLR最重要的特性之一了,在运行时,CLR总是知道一个对象的类型。在C#中可以调用GetType()来返回调用对象的类型,并且由于GetType()继承于System.Object对象,并且为非虚的方法,所以一个类型不可能通过重写此方法而伪装成另一种类型。
由于在开发的过程中,经常会需要将一个对象从一种类型转换为其他的类型,所以CLR允许将一个对象强制转换成它本身所引用的类型或派生其的基类型。一个对象向其父类的转换CLR认为是一种安全的隐式转换,不需要任何特殊的然而需要将一个对象转换为其派生类型时,则需要进行显示的转换,因为这样的转换可能在运行时失败。
下面来看一个例子:
1namespace LearnProject {
2 class Program {
3
4 static void Main(string[] args)
5 {
6 //此类型转换不需要显示的进行,因为new返回的对象类型为Student
7 //Person是Student的基类
8 Person student = new Student();
9 student.Eat();
10 //虚方法Work()在子类Student中被重写 [多态的应用]
11 student.Work();
12 //使用Object类型的变量去保存Student对象的引用依然不需要进行任何显示的转换
13 //任何类型均是由System.Object派生而来
14 Object objStudent = new Student();
15
16 //将Object类型objStudent转换成其派生类型Student则需要强制类型转换
17 Student studentObj = (Student)objStudent;
18
19 Program p = new Program();
20 //编译器会自动检测将要进行强制类型转换的对象是否为目标类型的基类或者派生类型,如果不是则在编译期出现错误
21 Student studentProgram = (Student)p;
22
23 //然而此用显式的转换则能够正常通过编辑,但是会在运行时抛出一个InvalidCastException异常
24 Object obj = new Program();
25 Student studentObj2 = (Student)obj;
26 }
27 }
28}
1 public class Person
2 {
3 public void Eat()
4 {
5 Console.WriteLine("吃饭");
6 }
7 public virtual void Work()
8 {
9 Console.WriteLine("工作");
10 }
11 }
12 public class Teacher : Person
13 {
14 public override void Work()
15 {
16 Console.WriteLine("教书");
17 }
18 }
19 public class Student : Person
20 {
21 public override void Work()
22 {
23 Console.WriteLine("没有工作,需要上学");
24 }
25 }