review——C# (15)转换

FROM P286

1.数字的转换

1.1溢出检测上下文

显示转换可能会丢失数据并且不能在目标类型中同等地表示源值。对于整数类型,C#给我们提供了选择运行时是否应该在进行类型转换时检测结果溢出的能力。通过checked运算符和checked语句来实现。

□代码片段是否被检查称作溢出检测上下文

--如果我们指定一个表达式或一段代码为checked,CLR会在转换产生溢出时抛出一个OverFlowException异常。

--如果代码不是checked,转换会继续而不管是否产生溢出

(1)checked和unchecked运算符

*控制表达式的溢出检测上下文。表达式放置在一对圆括号内并且不能是一个方法。语法如下:

checked(表达式)、unchecked(表达式)

(2)checked语句和unchecked语句

作为运算符时用于圆括号内的单个表达式。而用作语句时执行相同的功能,但控制的是一块代码中的所有转换,而不是单个表达式。

□checked语句和unchecked语句可以被嵌套在任意层次

2.引用转换

引用类型对象由内存中的两部分组成:引用和数据

□由引用保存的那部分信息是它指向的数据类型

□引用类型接受源引用并返回一个指向堆中同一位置的引用,但是把引用“标记”为其他类型

 

2.1隐式引用转换

与语言为我们自动实现的隐式数字转换类似,还有隐式引用转换。

□所有引用类型可以被隐式转换为object类型。

□任何类型可以隐式转换到它继承的接口

□类可以隐式转换到

--它继承链中的任何类

--它实现的任何接口

 

 

 2.2显式引用转换

显式引用转换是从一个普通类型到一个更精确类型的引用转换。

包括:

--从object到任何引用类型的转换

--从基类到从它继承的类的转换

□倒转16-18、16-19的箭头方向,即可以演示显式引用转换。

如果转换的类型不受限制,很可能会导致我们很容易地尝试引用在内存中实际并不存在的类成员。然而,编译器确实允许这样的转换。到那时,若系统在运行时遇到它们则会抛出一个异常。

2.3有效显示引用转换

(1)显示转换是没有必要的。即,语言已经为我们进行了隐式转换。e.g.

 

(2)源引用是null。e.g.,在下面的代码中,即使转换基类的引用到衍生类的引用通常会是不安全的,但由于源引用是null,这种转换还是允许的。

(3)由源引用指向的实际数据可以安全地进行隐式转换。

3.装箱操作  (值=》引用)

包括值类型在内的所有C#类型都派生自object类型。然而,值类型是高效轻量的类型,因为默认情况下在堆上不包括它们的对象组件。然而,如果需要对象组件,可以使用装箱(boxing)。装箱是一种隐式转换,它接收值类型的值,根据这个值在堆上创建一个完整的引用类型对象并返回对象引用。

3.1装箱是创建副本

一个有关装箱的普遍误解是在被装箱的项上发生了一些操作。其实不是,它返回的是值引用类型副本。在装箱产生之后,该值有两份副本,原始值类型和引用类型副本,每一个都可以独立操作。

 

4.拆箱转换  (引用=》值)

拆箱(unboxing)是把装箱后的对象转回值类型的过程。

□拆箱是显示转换

□系统在把值拆箱城ValueTypeT时执行了如下的步骤:

--它检测到要拆箱的对象实际上是ValueTypeT的装箱值。

--它把对象的值赋值到变量

 

 

5.is运算符

  如先前所说,有些转换是不成功的,并且会在运行时抛出一个InvalidCastException异常,我们可以使用is运算符来检查转换是否会成功完成,从而避免盲目尝试转换。

Expr is TargetType   返回bool 

如果Expr可以通过以下方式成功转换成目标类型,则返回true

□引用转换

□装箱操作

□拆箱操作(未找到例子)

通过装箱操作可转换成目标类型的例子:

        static void Main(string[] args)
        {
            int t = 5;
            object k = t;
            if (k is int)
                Console.WriteLine("!!");    
            Console.Read();
        }

输出!!,说明k is int 判断返回true。即对于某装箱结果进行判断时,会自动将其拆箱结果与目标类型进行比较。

关于is的官方文档(必看,有的内容更加详细)

6.as运算符

as运算符和强制转换运算符类似,只是它不抛出异常。如果转换失败,它返回null,而不是抛出异常。

和is运算符类似,as运算符只能用于引用转换和装箱转换,不能用于用户自定义转换或到值类型的转换。

 

posted @ 2018-06-04 10:12  perplex  阅读(245)  评论(0编辑  收藏  举报