码迷,mamicode.com
首页 > 编程语言 > 详细

类型与通用语言运行时:类型转换

时间:2016-08-19 13:10:23      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:

CLR 最重要的一个特性就是类型安全。CLR 在运行时总能知道一个对象的类型。我们也可以用过调用 GetType方法来得到对象的准确类型。因为该方法是一个虚方法。所以我们不可能利用它来篡改一个类型的信息。

例如:我们不可能重写 Employee 类的 GetType方法使之返回一个SpaceShuttle类型。

作为开发人员,我们经常会遇到需要将一个对象转换为其他类型。 CLR 允许我们将对象转换为其原来的类型或者它的任何一个基类型。各个编程语言自己决定如何提供这些转型操作。

例如,C# 不需要任何特殊的语法就可以将对象转换为其任何一个基类型,因为转换为基类型被认为是安全的隐式操作。然而在其将对象转换为它的任何派生类型时,C# 要求进行显式转换,因为这样的转型有可能会失败

下面的代码将演示如何将对象转化为它的基类和派生类型:

技术分享
 1 //该类型隐式继承自 System.Object
 2 class Employee{
 3      ...   
 4 }
 5 
 6 class App{
 7     public static void Main(){
 8  
 9     //这里不需要转型,因为 new 返回的是一个 Employee 对象
10     //而 Object 又是   Employee 的基类型
11      Object  o = new Object ();
12 
13     //这里需要转型,因为 Employee  继承自 Object 
14     //其它一些语言可能不需要转型
15    Employee   e = ( Employee )o;
16     
17 }
18 }
View Code

 上面的例子显示了要使代码通过编译我们需要做的一些事情,下面解释运行时发生的行为,在运行时CLR会检查转型操作以确保总是将对象转型它的实际类型、或者它的任何基类型。

例如,下面的代码虽然能够通过编译,但是运行时,却会抛出 InvalidCastException 异常:

技术分享
 1 class Manager:Employee {
 2 
 3   ...
 4 
 5 }
 6 
 7 
 8 class App{
 9 
10   public static void Main() {
11 
12     //构造一个 Manager 对象并将其传递给 PromoteEmployee
13 
14     //一个 Manager " Is-A" Object.PromoteEmployee 将正常运行
15 
16     Manager  m = new Manager();
17 
18     PromoteEmployee(m);
19 
20 
21     //构造一个DateTime 对象并将其传递给 PromoteEmployee
22 
23     //由于 DateTime 并非继承自 Employee,因此 PromoteEmployee 会抛出一个 System.InvalidCastException 异常
24 
25     DateTime newYears = new DateTime(2016,1,1);
26 
27     PromoteEmployee(newYears);
28 
29 }
30 
31   public static void PromoteEmployee(Object o) {
32 
33     //这里,编译器并不知道对象 o 引用的实际类型,所以编译器允许代码通过编译
34 
35     //当代码运行时,CLR会获知 o 的引用类型(每当进行转型操作时),
36 
37     //并且会检查对象的类型是否是Employee,或者是任何继承自Employee的类型
38 
39     Employee e = (Employee) o;
40 
41     ...
42 
43 }
44 
45 }
View Code

如果 CLR 允许上例中的转型操作,代码则会失去类型安全,并且结果也将变得不可预期——包括应用程序可能崩溃、以及由于类型欺骗引起的安全漏洞。

类型欺骗是很多安全漏洞的原因,它会极大地危机应用程序的 稳定性和健壮性。

 

* PromoteEmployee()的正确定义应该是接受一个 Employee对象,而不是 Object 对象作为参数,本文使用 Object 的目的仅仅只是为了演示编译器和 CLR 是如何处理转型操作的。

类型与通用语言运行时:类型转换

标签:

原文地址:http://www.cnblogs.com/Vanilla-611/p/5787034.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!