文章教程

3.6类型转换

8/31/2020 9:56:04 PM 人评论 次浏览

图片 1 知识点讲解:光盘:视频\PPT讲解(知识点)\第3章\类型转换.mp4

在计算机中,所有的数据都是由0和1构成的。C#中最简单的类型是char,它可以用一个数字表示Unicode字符集中的一个字符。在默认情况下,不同类型的变量使用不同的方式来表示数据。这意味着在变量值经过移位处理后,所得到的结果将会不同。为此,就需要类型转换来解决上述问题。C#中的类型转换有隐式转换和显式转换两种,本节将详细讲解这两种类型转换的基本知识。

隐式转换是系统的默认转换方式,即不需要特别声明即可在所有情况下进行。在进行C#隐式转换时,编译器不需要进行检查就能进行安全的转换处理。C#的隐式转换一般不会失败,也不会导致信息丢失。例如,下面的代码使变量值从int类型隐式地转换为了long类型。

int mm=20;
long nn=mm;

在C#中,允许对简单类型变量进行隐式转换,但是其中的bool和string类型变量是不能被隐式转换的。编译器可以隐式执行的数值转换类型如表3-5所示。

表3-5 C#中可隐式转换的数值类型列表

类  型

可转换的类型

byte

short、ushort、uint、int、ulong、long、float、double、decimal

sbyte

short、int、long、float、double、decimal

short

int、long、double、decimal

ushort

uint、int、ulong、long、float、double、decimal

int

long、float、double、decimal

uint

ulong、long、float、double、decimal

long

float、double、decimal

ulong

float、double、decimal

float

double

char

ushort、uint、int、ulong、long、float、double、decimal

顾名思义,显式转换是一种强制性的转换方式。在使用显式转换时,必须在代码中明确地声明要转换的类型。这就意味着需要编写特定的额外代码,并且代码的格式会随着转换方式的不同而不同。

虽然C#允许变量进行显式转换,但需要注意下面两点。

  • 隐式转换是显式转换的一种特例,所以允许将隐式转换书写成显式转换的格式。
  • 显示转换并不安全,因为不同类型的变量取值范围是不同的,所以如果强制执行显示转换,则可能会造成数据的丢失。

C#显式转换的语法格式如下。

类型 变量名=(类型)变量名

可从下面的2段代码中看出显式转换和隐式转换的区别。隐式转换的代码如下。

int mm=20;
long nn=mm;                    //隐式转换

显式转换的代码如下。

int mm=20;
long nn=(long)mm;                  //显式转换

显式转换是从一个数值类型向另一个数值类型进行转换的过程,由于显式转换包括隐式转换,所以总能将表达式从任何数值类型强制转换为其他任何类型,虽然在转换过程中会出现数据丢失。

编译器可显式转换的数值类型如表3-6所示。

表3-6 C#可显式转换的数值类型列表

类  型

可转换的类型

byte

sbyte、char

sbyte

byte、ushort、uint、ulong、char

short

sbyte、byte、ushort、uint、ulong、long、char

ushort

sbyte、byte、short、char

int

sbyte、byte、short、ushort、uint、ulong、char

uint

sbyte、byte、short、ushort、int、char

long

sbyte、byte、short、ushort、uint、int、ulong、char

ulong

sbyte、byte、short、ushort、uint、int、long、char

float

sbyte、byte、short、ushort、uint、int、ulong、long、char、float

char

sbyte、byte、short

decimal

sbyte、byte、short、ushort、uint、int、ulong、long、char、float、double

double

sbyte、byte、short、ushort、uint、int、ulong、long、char、float、decimal

C#中的值类型和引用类型在实质上讲是同源的,所以不但可以在值类型与值类型之间、引用类型与引用类型之间进行转换,也可以在值类型和引用类型之间进行转换。但是由于两者使用的内存类型不同,使它们之间的转换变得比较复杂。在C#中,通常将值类型转换为引用类型的过程称为装箱,将引用类型转换为值类型的过程称为拆箱。

装箱和拆箱是整个C#类型系统的核心模块,在值类型和引用类型之间架起了一座桥梁。最终使任何值类型的值都可以转换为object类型值,object类型值也可以转换为任何类型的值,并把类型值作为一个对象来处理。

下面对装箱与拆箱的基本知识进行简要介绍。

1.装箱

装箱允许将值类型转换为引用类型,转换规则如下。

  • 从任何的值类型到类型object的转换。
  • 从任何的值类型到类型System.ValueType的转换。
  • 从任何的值类型到值类型的接口转换。
  • 从任何枚举类型到类型System.Enum的转换。

在C#中,将一个值类型装箱为一个引用类型的过程如下。

(1)在托管堆中创建一个新的对象实例,并分配对应的内存。

(2)将值类型变量值复制到对象实例中。

(3)将对象实例地址复制到堆栈中,并指向一个引用类型。

实例002 演示C#装箱操作的实现过程

源码路径 光盘\daima\3\2\  视频路径 光盘\视频\实例\第3章\002

实例文件Zhuangxiang.cs的实现代码如下。

namespace Zhuangxiang
{
  class Program
  {
     public static void Main()
  {
    int mm = 50;    // 定义值类型变量 
    object nn = mm;  // 将值类型变量值装箱到引用类型对象 
    Console.WriteLine("值为{0},装箱对象为{1}", mm, nn);
    mm = 100;    // 改变值
    Console.WriteLine("值为{0},装箱对象为{1}", mm, nn);
    Console.ReadKey();
  }
  }
}
范例003:泛型委托和Lamdba实现计算器
源码路径:光盘\演练范例\003视频路径:光盘\演练范例\003范例004:整型数组排序
源码路径:光盘\演练范例\004视频路径:光盘\演练范例\004\

在上述实例代码中,首先定义了变量mm的数值类型为int,且初始值为50;然后对mm的值进行装箱处理为对象nn,具体过程如下。

  • 将变量mm的值50进行装箱,转换为对象nn。
  • 将变量mm的值修改为100,然后进行装箱,转换为对象nn。

经过“csc /out:zhuangxiang.exe zhuangxiang.cs”命令编译处理后,程序执行结果如图3-6所示。

{ZT]2XJBJ$TL0@(0R884YSY

图3-6 实例执行结果

2.拆箱

拆箱允许将引用类型转换为值类型,具体说明如下。

  • 从类型object到任何值类型的转换。
  • 从类型System.ValueType到任何值类型的转换。
  • 从任何的接口类型到对应的任何值类型的转换。
  • 从类型System.Enum到任何枚举类型的转换。

在C#中,将一个值类型拆箱为一个引用类型的过程如下。

(1)检查该对象实例是否为某个给定的值类型装箱后的值。

(2)如果是,则将值从实例中复制出来。

(3)赋值给值类型变量。

实例003 演示拆箱操作的实现过程

源码路径 光盘\daima\3\3\  视频路径 光盘\视频\实例\第3章\003

实例文件chaixiang.cs的主要实现代码如下。

namespace Chaixiang
{
  class Program
  {
    public static void Main()
    {
     int mm = 50; // 定义值类型变量 
     // 将值类型变量装箱到引用类型对象
     object nn = mm;
     Console.WriteLine("装箱:值为{0},装箱对象为{1}", mm, nn);
     int zz = (int)nn;      // 取消装箱
     Console.WriteLine("拆箱:装箱对象为{0},值为{1}", nn, zz);
     Console.ReadKey();
   }
  }
}
范例005:使用LINQ与正则表达式筛选聊天记录
源码路径:光盘\演练范例\005视频路径:光盘\演练范例\005范例006:检索XML文档中的数据
源码路径:光盘\演练范例\006视频路径:光盘\演练范例\006\

在上述代码中,首先定义了变量mm的数值类型为int,且初始值为50;然后对mm的值进行装箱处理为对象nn,具体过程如下。

  • 将变量mm的值50进行装箱,转换为对象nn。
  • 将变量nn的值进行拆箱处理,转换为变量zz。

经过“csc /out:zhuangxiang.exe zhuangxiang.cs”命令编译处理后,程序执行结果,如图3-7所示。

VFE19V640RQS)$B~~J45876

图3-7 实例执行结果

在上述拆箱处理过程中,必须保证变量的类型前后一致,否则将会出现异常。例如,将上述实例中的拆箱处理代码进行如下修改:

double zz = (double)nn;

修改后的执行结果如图3-8所示。

H~{FSCK7SCL%N8YBDQ%Z}DJ

图3-8 实例执行结果

从图3-8所示的执行结果可以看出,程序只执行了装箱操作,而没有执行拆箱操作。如果使用Visual Studio 2012运行,则会在其中输出异常提示信息,如图3-9所示。

图片 15

图3-9 Visual Studio 2012的异常提示

教程类别