C#高级编程.第6章 运算符和类型强制转换

上传人:琴**** 文档编号:19520616 上传时间:2017-11-19 格式:DOC 页数:30 大小:213KB
返回 下载 相关 举报
C#高级编程.第6章  运算符和类型强制转换_第1页
第1页 / 共30页
C#高级编程.第6章  运算符和类型强制转换_第2页
第2页 / 共30页
C#高级编程.第6章  运算符和类型强制转换_第3页
第3页 / 共30页
C#高级编程.第6章  运算符和类型强制转换_第4页
第4页 / 共30页
C#高级编程.第6章  运算符和类型强制转换_第5页
第5页 / 共30页
点击查看更多>>
资源描述

《C#高级编程.第6章 运算符和类型强制转换》由会员分享,可在线阅读,更多相关《C#高级编程.第6章 运算符和类型强制转换(30页珍藏版)》请在金锄头文库上搜索。

1、第 6 章 运算符和类型强制转换前几章介绍了使用 C#编写程序所需要的大部分知识。本章将首先讨论基本语言元素,接着论述 C#语言的扩展功能。本章的主要内容如下: C#中的可用运算符 处理引用类型和值类型时相等的含义 基本数据类型之间的数据转换 使用装箱技术把值类型转换为引用类型 通过强制转换技术在引用类型之间转换 重载标准的运算符,以支持对定制类型的操作 给定制类型添加强制转换运算符,以支持无缝的数据类型转换6.1 运算符C 和 C+开发人员应很熟悉大多数 C#运算符,这里为新程序员和 Visual Basic 开发人员介绍最重要的运算符,并介绍 C#中的一些新变化。C#支持表 6-1 所示的

2、运算符。表 6-1类 别 运 算 符算术运算符 + * / %逻辑运算符 & | & | !字符串连接运算符 +增量和减量运算符 + 移位运算符 比较运算符 = != =赋值运算符 = += = *= /= %= &= |= = =成员访问运算符(用于对象和结构 ) .索引运算符(用于数组和索引器 ) 数据类型转换运算符 ()条件运算符 (三元运算符) ?:委托连接和删除运算符(见第 7 章) + 对象创建运算符 new类型信息运算符 sizeof (只用于不安全的代码) is typeof as溢出异常控制运算符 checked unchecked间接寻址运算符 * & (只用于不安全代码)

3、 命名空间别名限定符(见第 2 章) :空接合运算符 ?有 4 个运算符(sizeof、*、-、&)只能用于不安全的代码(这些代码绕过了 C#类型安全性的检查) ,这些不安全的代码见第 12 章的讨论。还要注意,sizeof 运算符在.NET Framework 1.0 和 1.1 中使用,它需要不安全模式。自从.NET Framework 2.0 以来,就没有这个运算符了。类 别 运 算 符运算符关键字 sizeof(仅用于.NET Framework 1.0 和 1.1)运算符 *、&使用 C#运算符的一个最大缺点是,与 C 风格的语言一样,赋值 (=)和比较(=)运算使用不同的运算符。例

4、如,下述语句表示x 等于 3:x = 3;如果要比较 x 和另一个值,就需要使用两个等号(=):if (x = 3)C#非常严格的类型安全规则防止出现常见的 C#错误,也就是在逻辑语句中使用赋值运算符代替比较运算符。在 C#中,下述语句会产生一个编译错误:if (x = 3)习惯使用宏字符&来连接字符串的 Visual Basic 程序员必须改变这个习惯。在 C#中,使用加号+连接字符串,而& 表示两个不同整数值的按位 AND 运算。| 则在两个整数之间执行按位 OR 运算。Visual Basic 程序员可能还没有使用过(取模) 运算符,它返回除运算的余数,例如,如果 x 等于 7,则 x

5、% 5 会返回 2。在 C#中很少会用到指针,因此也很少用到间接寻址运算符(-)。使用它们的唯一场合是在不安全的代码块中,因为只有在此 C#才允许使用指针。指针和不安全的代码见第 12章。6.1.1 运算符的简化操作表 6-2 列出了 C#中的全部简化赋值运算符。表 6-2运算符的简化操作 等 价 于x+, +x x = x + 1x , x x = x 1x+= y x = x + yx= y x = x yx *= y x = x * yx /= y x = x / yx %= y x = x % yx = y x = x yx = b)Console.WriteLine(a = b);e

6、lseConsole.WriteLine(a 关系运算符 = is as比较运算符 = = !=按位 AND 运算符 &按位 XOR 运算符 按位 OR 运算符 |布尔 AND 运算符 &布尔 OR 运算符 |条件运算符 ?:赋值运算符 = += = *= /= %= &= |= = = =注意:在复杂的表达式中,应避免利用运算符优先级来生成正确的结果。使用括号指定运算符的执行顺序,可以使代码更整洁,避免出现潜在的冲突。6.2 类型的安全性第 1 章提到中间语言(IL)可以对其代码强制加上强类型安全性。强类型支持.NET 提供的许多服务,包括安全性和语言的交互性。因为 C#这种语言会编译为 I

7、L,所以 C#也是强类型的。这说明数据类型并不总是可互换的。本节将介绍基本类型之间的转换。注意:C#还支持在不同引用类型之间的转换,允许指定自己创建的数据类型如何与其他类型进行相互转换。这些论题将在本章后面讨论。泛型是 C#中的一个特性,它可以避免对一些常见的情形进行类型转换,泛型详见第 9章。6.2.1 类型转换我们常常需要把数据从一种类型转换为另一种类型。考虑下面的代码:byte value1 = 10;byte value2 = 23;byte total;total = value1 + value2;Console.WriteLine(total);在编译这些代码时,会产生一个错误:

8、Cannot implicitly convert type int to byte (不能把 int 类型隐式地转换为 byte 类型)。问题是,我们把两个 byte 型数据加在一起时,应返回 int 型结果,而不是另一个byte。这是因为 byte 包含的数据只能为 8 位,所以把两个 byte 型数据加在一起,很容易得到不能存储在 byte 变量中的值。如果要把结果存储在一个 byte 变量中,就必须把它转换回byte。C# 有两种转换方式:隐式转换方式和显式转换方式。1. 隐式转换方式只要能保证值不会发生任何变化,类型转换就可以自动进行。这就是前面代码失败的原因:试图从 int 转换为

9、 byte,而潜在地丢失了 3 个字节的数据。编译器不会告诉我们该怎么做,除非我们明确告诉它这就是我们希望的!如果在 long 型变量中存储结果,而不是byte 型变量中,就不会有问题了:byte value1 = 10;byte value2 = 23;long total; / this will compile finetotal = value1 + value2;Console.WriteLine(total);这是因为 long 类型变量包含的数据字节比 byte 类型多,所以数据没有丢失的危险。在这些情况下,编译器会很顺利地转换,我们也不需要显式提出要求。表 6-4 介绍了 C#

10、支持的隐式类型转换。表 6-4源 类 型 目 的 类 型sbyte short、int、long、float、double 、decimalbyte short、ushort、int、uint、long 、ulong 、float、double、decimalshort int、long、float、double 、decimalushort int、uint、long、ulong、float、double、decimalint long、float 、double、decimaluint long、ulong、float、double、decimallong、ulong float、doub

11、le、decimalfloat doublechar ushort、int、uint、long、ulong、float、double、decimal注意,只能从较小的整数类型隐式地转换为较大的整数类型,不能从较大的整数类型隐式地转换为较小的整数类型。也可以在整数和浮点数之间转换,其规则略有不同,可以在相同大小的类型之间转换,例如 int/uint 转换为 float,long/ulong 转换为 double,也可以从 long/ulong 转换回 float。这样做可能会丢失 4 个字节的数据,但这仅表示得到的 float 值比使用 double 得到的值精度低,编译器认为这是一种可以接受的

12、错误,而其值的大小是不会受到影响的。无符号的变量可以转换为有符号的变量,只要无符号的变量值的大小在有符号的变量的范围之内即可。在隐式转换值类型时,可空类型需要额外考虑: 可空类型隐式转换为其他可空类型,应遵循表 6-4 中非可空类型的转换规则。即 int? 隐式转换为 long?、float?、double?和 decimal?。 非可空类型隐式转换为可空类型也遵循表 6-4 中的转换规则,即 int 隐式转换为long?、float?、 double?和 decimal?。 可空类型不能隐式转换为非可空类型,此时必须进行显式转换,如下一节所述。这是因为可空类型的值可以是 null,但非可空类

13、型不能表示这个值。2. 显式转换方式有许多场合不能隐式地转换类型,否则编译器会报告错误。下面是不能进行隐式转换的一些场合: int 转换为 short- 会丢失数据 int 转换为 uint- 会丢失数据 uint 转换为 int- 会丢失数据 float 转换为 int- 会丢失小数点后面的所有数据 任何数字类型转换为 char - 会丢失数据 decimal 转换为任何数字类型- 因为 decimal 类型的内部结构不同于整数和浮点数 int? 转换为 int- 可空类型的值可以是 null 但是,可以使用 cast 显式执行这些转换。在把一种类型强制转换为另一种类型时,要迫使编译器进行转

14、换。类型转换的一般语法如下:long val = 30000;int i = (int)val; / A valid cast. The maximum int is 2147483647这表示,把转换的目标类型名放在要转换的值之前的圆括号中。对于熟悉 C 的程序员来说,这是数据类型转换的典型语法。对于熟悉 C+数据类型转换关键字(如 static_cast)的程序员来说,这些关键字在 C#中不存在,必须使用 C 风格的旧语法。这种类型转换是一种比较危险的操作,即使在从 long 转换为 int 这样简单的转换过程中,如果原来 long 的值比 int 的最大值还大,就会出问题:long va

15、l = 3000000000;int i = (int)val; / An invalid cast. The maximum int is 2147483647在本例中,不会报告错误,也得不到期望的结果。如果运行上面的代码,结果存储在i 中,则其值为:-1294967296最好假定显式数据转换不会给出希望的结果。如前所述,C#提供了一个 checked 运算符,使用它可以测试操作是否会产生算术溢出。使用这个运算符可以检查数据类型转换是否安全,如果不安全,就会让运行库抛出一个溢出异常:long val = 3000000000;int i = checked (int)val);记住,所有的显式数据类型转换都可能不安全,在应用程序中应包含这样的代码,处理可能失败的数据类型转换。第 14 章将使用 try 和 catch 语句引入结构化异常处理。使用数据类型转换可以把大多数数据从一种基本类型转换为另一种基本类型。例如:给 price 加上 0.5,再把结果转换为 int:double price = 25.30;int approximatePrice = (int)(price + 0.5);这么做的代价是把价格四舍五入为最接近的美元数。但在这个转换过程中,小数点后面的所有数据都会丢失。因此,如果要使用这个修改过的价格进行更多的计算,最好不要使用这种转换;如果要输出

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号