第2章 数据类型
C#具有各式各样的数据类型,大致上分成两大部分:值类型和引用类型。值数据类型的变量在传递的时候,传递的是数据的值;引用数据类型的变量在传递的时候,传递的是数据的地址。
C#的简单类型、结构和枚举都属于值类型。类、代理、数组和接口属于引用类型。其中,简单类型包括布尔类型、字符类型、整数类型和实数类型。
2.1 C#数据类型与比较
在C#中,根据数据类型的不同,变量存储在两个不同的位置。
第一个位置是程序的堆栈,每个程序都有自己的堆栈,其他程序是不能直接访问的。在程序的方法被调用时,所有的本地变量都放入程序的堆栈,调用完毕后,变量出栈并检索。
第二个位置是托管内存中的堆,在程序运行的过程中,CLR定期检查并清理堆中不能访问的变量,释放该变量占用的内存。
存储在第一个位置的数据类型就是值类型,存储在第二个位置的数据类型就是引用类型。
当值类型的变量被赋值时,在堆栈中创建的是两个相同的数据副本,其中一个变量值的改变,不会引起另外一个变量的改变。当引用类型的变量被赋值时,在内存堆中创建的是对同一个位置的两个引用。
本示例对值数据类型和引用数据类型进行比较,显示这两种数据类型的差别。
技术要点
本示例定义了值数据类型和引用数据类型,显示赋值以后对原变量的改变,技术要点如下。
● 在C#语言中,结构是值类型的数据类型,类是引用类型的数据类型。
● 当两个变量之间进行赋值操作时,例如A=B,A和B均为值类型数据类型的变量时,修改B的值,不会影响A变量;A和B均为引用类型数据类型的变量时,修改B的值,将同时改变A的值。
实现步骤
(1)创建控制台应用程序项目,命名为“DifferencesBetweenValueAndReference”。
(2)打开并编辑Program.cs文件,代码如下所示。
using System; using System.Collections.Generic; using System.Text; namespace DifferencesBetweenValueAndReference { class Program { static void Main(string[] args) { //结构是值类型的数据类型 strcEmployee strcemp1 = new strcEmployee(); strcemp1.strFirstName = "Michael"; strcemp1.strLastName = "Suyama"; strcEmployee strcemp2 = strcemp1; strcemp2.strFirstName = "Robert"; strcemp2.strLastName = "King"; //类是引用类型的数据类型 clsEmployee clsemp1 = new clsEmployee(); clsemp1.strFirstName = "Michael"; clsemp1.strLastName = "Suyama"; clsEmployee clsemp2 = clsemp1; clsemp2.strFirstName = "Robert"; clsemp2.strLastName = "King"; //显示赋值后原变量的数据变化 Console.WriteLine(strcemp1.strFirstName + " " + strcemp1.strLastName); Console.WriteLine(clsemp1.strFirstName + " " + clsemp1.strLastName); Console.ReadLine(); } struct strcEmployee//员工结构的定义 { public string strFirstName; public string strLastName; } class clsEmployee//员工类的定义 { public string strFirstName; public string strLastName; } } }
(3)按F5键运行程序。程序运行结果如下所示。
Michael Suyama Robert King!
源程序解读
(1)在本示例中,首先在两个值类型的变量之间赋值,然后修改其中一个变量的值,接着在两个引用类型的变量之间赋值,并且修改其中一个变量的值,最后,通过显示原始变量的值,比较值类型和引用类型的主要区别。
(2)C#结构中的成员访问权限默认为private,和C++编程语言不同,C++编程语言中结构成员的访问权限默认为public。本示例在定义结构成员时,需要在定义语句前添加public关键字,以便于外部程序访问。
2.2 decimal类型的格式化
C#的数据类型具有多种输出格式,其中标准数字类型具有多种形式的格式化字符串,以及自定义格式字符串。
本示例通过decimal类型变量的格式化输出,演示数据类型的多种标准数字类型格式化字符串输出和自定义格式字符串输出。
技术要点
本示例主要使用decimal数据类型的ToString方法,通过指定该方法格式化字符串参数,实现decimal类型不同格式的输出字符串,技术要点如下。
● 标准数字格式字符串产生的格式化字符串,会受到控制面板中“区域设置”的本地化设置影响。
● 在String.Format、TextWriter.WriteLine和Console.WriteLine方法中,可以对数据变量使用复合格式化。
● 复合格式化格式项的语法是:{index[,alignment][:formatString]}。其中index表示从0开始的列表元素索引值,alignment表示对齐格式,正值表示右对齐,负值表示左对齐,
该值的绝对值表示字符宽度,formatString表示标准或自定义的格式说明符。
实现步骤
(1)创建控制台应用程序项目,命名为“DecimalFormat”。
(2)打开并编辑Program.cs文件,代码如下所示。
using System; using System.Collections.Generic; using System.Text; namespace DecimalFormat { class Program { static void Main(string[] args) { decimal mydcm = 12.34567m; Console.WriteLine(mydcm.ToString("c"));//货币格式 Console.WriteLine("|{0,-10:c3}|",mydcm); Console.WriteLine(mydcm.ToString("e"));//科学计数法 Console.WriteLine("|{0,-10:e2}|", mydcm); Console.WriteLine(mydcm.ToString("f3"));//浮点格式 Console.WriteLine("|{0,-10:f}|", mydcm); Console.WriteLine(mydcm.ToString("g"));//常规格式 Console.WriteLine("|{0,10:G}|", mydcm); Console.WriteLine(mydcm.ToString("n"));//数字格式 Console.WriteLine("|{0,10:n}|", mydcm); Console.WriteLine(mydcm.ToString("p3"));//百分比格式 Console.WriteLine("|{0,10:P}|", mydcm); Console.WriteLine(mydcm.ToString("#.000"));//自定义格式 Console.WriteLine(mydcm.ToString("#.000%")); Console.ReadLine(); } } }
(3)按Ctrl+F5组合键运行程序,运行结果如下所示。
¥12.35 |¥12.346 | 1.234567e+001 |1.23e+001 | 12.346 |12.35 | 12.34567 | 12.34567| 12.35 | 12.35| 1,234.567% | 1,234.57%| 12.346 1234.567%
源程序解读
(1)在实数后添加后缀“m”表示decimal数据类型。
(2)格式符“c”或“C”表示将decimal转换为货币格式的字符串。“c3”表示将decimal转换为精度为3位小数的货币格式字符串。
(3)格式符“e”或“E”表示将decimal转换为科学计数法格式的字符串。“e2”表示将decimal转换为精度为两位小数的科学计数法格式字符串。
(4)格式符“f”或“F”表示将decimal转换为固定浮点格式的字符串。“f3”表示将decimal转换为精度为3位小数的固定浮点格式字符串。
(5)格式符“g”或“G”表示将decimal转换为常规格式的字符串。
(6)格式符“n”或“N”表示将decimal转换为数字格式的字符串,其中小数点左边每3位数字中间插入一个千位分隔符。默认精度为两位小数。
(7)格式符“p”或“P”表示将decimal转换为百分比格式的字符串,其中小数点左边每3位数字中间插入一个千位分隔符。“p3”表示将decimal转换为精度为3位小数的百分比格式字符串。默认精度为两位小数。
(8)自定义数据格式字符串“#.000”,表示将decimal转换为保留整数部分的有效数字,精度为3位小数,小数位不足时补零字符串。
2.3 Object类型操作
在C# 语言的统一类型系统中,所有类型(预定义类型、用户定义类型、引用类型和值类型)都是直接或间接从Object类型继承的。可以将任何类型的值赋给Object类型的变量。将值类型的变量转换为对象的过程称为“装箱”。将对象类型的变量转换为值类型的过程称为“取消装箱”。本示例演示了装箱和取消装箱的程序实现方法,并指出实际应用中发生装箱和取消装箱时应该注意的地方。
技术要点
本示例主要使用Object类型的数据转换,实现装箱和取消装箱的功能,技术要点如下。
● 值类型的装箱,实际上是将值类型变量打包到Object类型的引用类型实例中。.NET Framework创建并构造新的引用类型实例,并为该实例分配受托管的内存,此时引用类型变量放置在托管内存堆中。
● 引用类型的取消装箱,是将object类型转换到值类型,实际上包含两个过程。第一个过程是检查object类型的引用类型实例,确保该实例可被取消装箱,第二个过程是创建新的值类型变量并赋值,此时新的值类型变量放置在程序的堆栈中。
● 调用以Object为参数的方法时,或者其他需要转换为Object的场合,值类型的数据将自动封装为引用类型的数据。
● 把Object类型的数据转换为值类型数据时,将自动进行取消封装。
实现步骤
(1)创建控制台应用程序项目,命名为“BoxingAndUnboxing”。
(2)在Program..cs文件中添加System.Collections命名空间的引用,代码如下所示。
using System.Collections;
(3)在Program.cs文件中添加结构APoint,代码如下所示。
struct APoint//描述点数据的结构 { public int X;//X坐标 public int Y;//Y坐标 public APoint(int point_X, int point_Y)//带参数的构造函数 { this.X = point_X; this.Y = point_Y; } public void Move(int offset_X, int offset_Y)//移动点坐标的方法 { X += offset_X; Y += offset_Y; } public override string ToString() //重载ToString方法 { return X.ToString()+","+Y.ToString(); } }
(4)在Program.cs文件中编写程序执行的入口方法Main,代码如下所示。
static void Main(string[] args) { Console.WriteLine("使用ArrayList"); ArrayList pnts = new ArrayList(3); for (int i = 0; i < 3; i++) { pnts.Add(new APoint(100,100));//ArrayList赋值 } for (int i = 0; i < 3; i++) { //ArrayList中的元素执行Move方法,伴随着装箱和取消装箱,原数组元素的值并未改变 ((APoint)pnts[i]).Move(400, 400); } for (int i = 0; i < 3; i++) { Console.WriteLine("第"+i.ToString()+"点的坐标是("+pnts[i].ToString()+")"); } Console.WriteLine("使用数组"); APoint[] points = new APoint[3]; for (int i = 0; i < 3; i++) { points[i]=new APoint(100, 100);//数组赋值 } Console.WriteLine("使用foreach循环"); foreach (APoint point in points) { //数组中的元素执行Move方法,在foreach循环中伴随装箱过程,原数组元素并未改变 point.Move(400, 400); } for (int i = 0; i < 3; i++) { Console.WriteLine("第" + i.ToString() + "点的坐标是(" + points[i].ToString() + ")"); } Console.WriteLine("使用for循环"); for (int i = 0; i < 3; i++) { //直接操作数组中的元素,没有装箱和取消装箱的过程,原数组的元素发生改变 points[i].Move(400, 400); } for (int i = 0; i < 3; i++) { Console.WriteLine("第" + i.ToString() + "点的坐标是(" + points[i].ToString() + ")"); } Console.ReadLine(); }
(5)按F5健运行程序,运行结果如下所示。
使用ArrayList 第0点的坐标是(100,100) 第1点的坐标是(100,100) 第2点的坐标是(100,100) 使用数组 使用foreach循环 第0点的坐标是(100,100) 第1点的坐标是(100,100) 第2点的坐标是(100,100) 使用for循环 第0点的坐标是(500,500) 第1点的坐标是(500,500) 第2点的坐标是(500,500)
源程序解读
(1)在C#中结构允许定义构造函数和方法,但不允许定义缺省的构造函数。
(2)ArrayList类的Add方法参数是Object,在添加点数据的时候,进行了封装操作,此时ArrayList数组的每一个元素都是Object类型,放置在托管内存堆中,在将ArrayList中的元素转换为APoint结构时,进行了取消封装的操作。此时位于程序堆栈中取消封装后的值类型变量,执行的Move方法并不会对位于托管内存中引用类型的ArrayList元素造成影响。从程序运行的结果发现,ArrayList中的点数据并未发生变化。
(3)在使用数组的情况下,数组中的每个元素都是位于程序堆栈的值类型数据,使用foreach循环时,foreach的参数IEnumerator和IEnumerable均为接口类型,此时自动进行了装箱操作,在foreach循环中执行的Move方法,是对托管内存中的引用类型变量进行的,并不会对位于程序堆栈中的值类型变量造成影响,从程序的运行结果发现,数组中的点数据并未发生变化。
2.4 string类型简单操作
string类型是一种特殊的引用类型,该类型的实例是“不可变的”,即string类型的实例一旦创建就无法更改。对字符串进行操作的方法实际上返回的是新的字符串对象。字符串的相等判断,只判断两个字符串变量的值是否相等。本示例说明了字符串的这些特点。
技术要点
本示例主要说明了string引用类型的一些特殊用法,技术要点如下。
● string类型是引用类型,具有引用类型的特征。在两个string变量之间使用“=”操作符赋值时,两个变量指向同一处分配的托管内存。
● string类型变量的值是不可变的,当一个string类型变量的值被修改时,实际上是创建了另外一个托管内存,并由该变量指向新的托管内存。这是由字符串长度的不确定性,必须重新分配托管内存的特点决定的。
● 和一般的引用类型相等判断不同,判断两个字符串是否相等,只判断两个字符串的值是否相等,而不是判断两个字符串变量是否指向同一处托管内存。这个特点简化了string类型的比较操作。
实现步骤
(1)创建控制台应用程序项目,命名为“SimpleString.”。
(2)打开并编辑Program.cs文件,代码如下所示。
using System; using System.Collections.Generic; using System.Text; namespace SimpleString { class Program { static void Main(string[] args) { string a = "Simple String"; //字符串是引用类型,使用“=”操作符赋值时,两个变量指向托管内存中的同一位置 string b = a; Console.WriteLine("说明string是引用类型的演示结果:" + ((object)a == (object)b)); b = "Changed";//修改字符串,将在托管内存中创建新的内存位置 Console.WriteLine("说明修改string将创建新实例的演示结果:" + ((object)a == (object)b)); b = "Simple String";//此时变量b在托管内存中的位置仍然与变量a不同 Console.WriteLine("说明string判断相等时只判断值的演示结果:" + (a == b)); Console.ReadLine(); } } }
(3)按F5键运行程序,运行结果如下所示。
说明string是引用类型的演示结果:True 说明修改string将创建新实例的演示结果:False 说明string判断相等时只判断值的演示结果:True
源程序解读
(1)在两个字符串变量之间使用“=”操作符,根据引用类型数据类型的特点,这两个字符串变量指向同一处托管内存分配空间,这时候两个字符串完全一致。
(2)当字符串变量b改变时,公共语言运行时(CLR)为字符串变量b创建一个新的托管内存空间,保存修改后的内容,并使字符串变量b指向这个新的托管内存空间。此时字符串变量b和字符串变量a不仅值不一样,所指向的托管内存分配空间也不一样。
(3)判断两个字符串相等。即使用“==”或“!=”操作符时,只根据字符串变量的值进行判断。在本示例中,字符串变量a和字符串变量b指向不同的托管内存空间,因为字值一样,所以判断结果是两者相等。
2.5 多种数字类型混合运算
C#中的数字类型可以互相转换,数字类型之间的转换分为两种,一种是隐式转换,一种是显式转换。显式转换必须声明转换的目的类型。
隐式转换允许的转换如表2.1所示。
表2.1 C#允许的隐式转换
显式转换允许的转换如表2.2所示。
表2.2 C#允许的显式转换
本示例演示了如何在多种不同的数字类型之间进行混合运算。
技术要点
本示例主要使用了数字类型的隐式转换和显式转换,使用不用的数字类型进行混合运算,技术要点如下。
● 实数后添加后缀“f”,表示一个float类型的数字。
● 实数后添加后缀“m”,表示一个decimal类型的数字。
● 数字类型的转换会引起数值变化,在实际编写程序的时候需要特别注意。
● 不同数字类型之间的计算,并非支持所有的操作符,在进行计算之前必须先完成类型转换。
实现步骤
(1)创建控制台应用程序项目,命名为“ConvertCompute.”。
(2)打开并编辑Program.cs文件,代码如下所示。
using System; using System.Collections.Generic; using System.Text; namespace ConvertCompute { class Program { static void Main(string[] args) { float flt = 11.66666666666f;//float数据类型赋值 decimal dcm = 1.735066843548275622311m;//decimal数据类型赋值 double dbl = (double)dcm;//将decimal转换为double Console.WriteLine("decimal {0}--double {1}",dcm,dbl); int myint = (int)flt;//将float转换为int Console.WriteLine("float {0}--int {1}",flt,myint); decimal res2 = myint * dcm; Console.WriteLine("int*decimal--{0}",res2); double res1 = flt * dbl; Console.WriteLine("float*double--{0}", res1); decimal res3 = (decimal)flt * dcm; Console.WriteLine("float*decimal--{0}",res3); Console.ReadLine(); } } }
(3)按F5键运行程序,运行结果如下所示。
decimal 1.735066843548275622311--double 1.73506684354828 float 11.66667--int 11 int*decimal--19.085735279031031845421 float*double--20.2424470596261 float*decimal--20.24245229161936075454707437
源程序解读
(1)第一个打印结果,说明将decimal数字类型转换为double数据类型时,数据值发生的变化,小数部分进行了四舍五入。
(2)第二个打印结果,说明将float数字类型转换为int数据类型时,数据值发生的变化,小数部分没有进行四舍五入。
(3)第三、第四和第五个打印结果,说明在进行数字转换后由于数据值产生变化,导致计算结果的差别。
(4)float数字类型和decimal数字类型之间不支持操作符“*”,必须将float变量转换为decimal类型,才能相乘得到一个decimal类型的结果。
2.6 结构体声明和初始化
C#中的结构是值类型的数据类型,结构位于程序堆栈区域,在表示简单数据类型组成的元素时,相对类而言具有更好的执行性能,可以视为轻量级的类。在使用结构的时候,需要注意结构是值类型这一特点。本示例在程序中声明和初始化结构,并说明了使用结构时的注意事项。
技术要点
本示例定义了一个简单数据类型组成的结构,并在程序中初始化和使用该结构,技术要点如下。
● 在结构声明中不能声明默认的无参数的构造函数,可以声明带参数的构造函数,为结构成员提供初始化的方法。
● 在结构声明中不允许对结构成员直接初始化实例字段。
● 结构不能继承和派生,可以实现接口。实现接口的方式与类相同。
● 从程序执行效率方面考虑,结构适合描述轻量级的、不包含引用数据类型的对象。
● 使用new关键字调用默认构造函数创建结构实例时,结构中的字段均未赋值。
● 不使用new关键字可以创建结构的实例,效果与使用默认构造函数创建结构实例相同。
实现步骤
(1)创建控制台应用程序项目,命名为“StructDeclareAndInitialize.”。
(2)打开并编辑Program.cs文件,代码如下所示。
using System; using System.Collections.Generic; using System.Text; namespace StructDeclareAndInitialize { class Program { static void Main(string[] args) { MyPen pen1 = new MyPen(1,1);//使用构造函数创建结构实例 MyPen pen2 = pen1;//使用操作符“=”赋值 MyPen pen3;//不使用构造函数直接声明结构变量 pen2.color = 2; pen2.size = 2; pen3.color = 1;//pen3的成员值与pen1成员值一致 pen3.size = 1; Console.WriteLine("pen1数据:Color {0} Size {1}", pen1.color, pen1.size); Console.WriteLine("pen2数据:Color {0} Size {1}", pen2.color, pen2.size); Console.WriteLine("pen3数据:Color {0} Size {1}", pen3.color, pen3.size); Console.WriteLine("pen3是否等于pen1:{0}",pen3.Equals(pen1)); Console.ReadLine(); } struct MyPen { public int color; public int size; //结构可以声明构造函数,但不能声明默认的、不带参数的构造函数 public MyPen(int iColor, int iSize) { color = iColor; size = iSize; } } } }
(3)按F5键运行程序,运行结果如下所示。
pen1数据:Color 1 Size 1 pen2数据:Color 2 Size 2 pen3数据:Color 1 Size 1 pen3是否等于pen1:True
源程序解读
(1)C#的结构数据类型,默认的字段访问权限是private,在结构声明中,必须在字段前面添加public关键字才能够被外部程序访问。
(2)在结构声明中可以声明带参数的构造函数。
(3)在结构声明中不允许初始化字段,例如在示例中将结构的color字段声明为public int color = 10,将会导致程序编译错误。
(4)C#语言中的结构类型属于值类型。在使用pen1给pen2赋值时,pen2和pen1的字段值是一致的,pen2是pen1的副本,当pen2的值发生改变时,不会影响pen1的字段值。
(5)pen3是不使用new关键字创建的结构实例,只要在后续程序中对结构进行初始化就可以正常使用该实例。
(6)当两个结构实例中的字段值完全一致时,这两个结构可以判断为相等。
2.7 枚举类型的格式化
枚举类型是一种特殊的值类型,该类型包含名称、基础数据类型和字段。枚举不能定义自己的方法、属性和事件,也不能实现接口。C#的枚举类型具有多种输出格式,本示例说明了如何在将枚举类型转换为字符串时指定输出格式。
技术要点
本示例主要使用了枚举类的ToString方法,将枚举类型转换为指定格式的字符串,技术要点如下。
● 枚举类型的基础数据类型通过继承基础数据类型指定,默认为Int32,可以指定为Byte、Int32或者UInt64。
● 枚举类型的声明可以指定字段的初始值,也可不指定初始值,而使用默认值按照声明的顺序,从0开始赋予字段初始值。
● 使用2的幂作为标志枚举时,枚举值能够使用按位“或”运算自由组合。
实现步骤
(1)创建控制台应用程序项目,命名为“FormatEnum.”。
(2)打开并编辑Program.cs文件,代码如下所示。
using System; using System.Collections.Generic; using System.Text; namespace FormatEnum { class Program { static void Main(string[] args) { //转换为常规字符串,如果事先未在枚举中定义,就转换为整数值字符串 Console.WriteLine("LightBlue(G)" + myColor.LightBlue.ToString("g")); //转换为字符串,如果事先未在枚举中定义,就转换为“,”分隔的名称列表 Console.WriteLine("LightBlue(F)" + myColor.LightBlue.ToString("f")); //将枚举整数值转换为字符串 Console.WriteLine("LightBlue(D)" + myColor.LightBlue.ToString("d")); //将枚举整数值转换为十六进制格式的字符串 Console.WriteLine("LightBlue(X)" + myColor.LightBlue.ToString("x")); myColor mc = myColor.Yellow | myColor.White; Console.WriteLine("LightYellow(G)" + mc.ToString("g")); Console.WriteLine("LightYellow(F)" + mc.ToString("f")); Console.WriteLine("LightYellow(D)" + mc.ToString("d")); Console.WriteLine("LightYellow(X)" + mc.ToString("x")); Console.ReadLine(); } [Flags]//声明标志枚举 enum myColor:byte { None = 0, Red = 1, Green = 2, Blue = 4, White = 8, Yellow = Red | Green, LightBlue = Blue | White } } }
(3)按F5键运行程序,运行结果如下所示。
LightBlue(G)LightBlue LightBlue(F)LightBlue LightBlue(D)12 LightBlue(X)0C LightYellow(G)Yellow, White LightYellow(F)Yellow, White LightYellow(D)11 LightYellow(X)0B
源程序解读
(1)本示例中,枚举声明语句enum myColor:byte指定枚举类型的基本数据类型为byte。
(2)格式符“g”或“G”表示将枚举转换为常规格式的字符串,如果要转换的枚举类型变量是在枚举声明中定义的,就转换为枚举声明中定义的字段名称。如果要转换的枚举类型变量未在枚举声明中定义,就将变量表示的整数转换为字符串。
(3)格式符“f”或“F”表示将枚举转换为字符串。如果要转换的枚举类型变量是在枚举声明中定义的,就转换为枚举声明中定义的字段名称。如果要转换的枚举类型变量未在枚举声明中定义,就以“,”分隔列举组成枚举变量的字段名称。
(4)格式符“d”或“D”表示将枚举整数值转换为字符串。
(5)格式符“x”或“X”表示将枚举整数值转换为十六进制格式的字符串。
2.8 字符类型与数字类型的转换
字符类型和数字类型可以实现互相转换,其中字符转换为数字类型,可以使用隐式转换进行,数字类型转换为字符类型,需要使用显式转换。
技术要点
本示例说明了如何在字符类型和数字类型之间进行转换,技术要点如下。
● 字符类型可以隐式转换为ushort、int、uint、long、ulong、float、double和decimal类型,不能从其他数据类型隐式转换为字符类型。
● 数字类型变量在转换为字符类型时,首先转换为整数类型,如果数字类型变量带有小数部分,就截掉小数部分,再转换为字符类型。
实现步骤
(1)创建控制台应用程序项目,命名为“CharToNumber.”。
(2)打开并编辑Program.cs文件,代码如下所示。
using System; using System.Collections.Generic; using System.Text; namespace CharToNumber { class Program { static void Main(string[] args) { char testchar1 = 'a'; int testint1 = testchar1;//隐式转换,将chat类型赋值给int类型 Console.WriteLine("字符{0}的整数值是:{1}", testchar1, testint1); decimal testdecimal2 = 114.9923m;//decimal类型变量赋值加后缀“m” char testchar2 = (char)testdecimal2;//显式转换,将decimal类型赋值给chat类型 Console.WriteLine("小数{0}表示的字符是:{1}", testdecimal2, testchar2); Console.ReadLine(); } } }
(3)按F5键运行程序,运行结果如下所示。
字符a的整数值是:97 小数114.9923表示的字符是:r
源程序解读
(1)本示例中使用隐式转换将字符类型变量testchar1转换为整数类型变量testint1。使用显式转换将数字类型变量testdecimal2转换为字符类型变量testchar2。
(2)将decimal类型的变量testdecimal2转换为字符时,实际上是先将testdecimal2不作四舍五入,直接获取整数部分,转换为整数值114,再将整数值114转换为字符r。