现在的位置: 首页 > 综合 > 正文

天轰穿C#教程之显示转换[原创]

2011年08月18日 ⁄ 综合 ⁄ 共 5912字 ⁄ 字号 评论关闭

  由于本章是属于本书的最最最基础部分,所以我们在讲述知识的同时也很注重学习方法和Visual Studio等工具的使用说明。

  

  显示转换就需要特殊类或者方法来辅助完成了。例如

  

  long lo = 1;                //申明一个long类型变量

  

  byte b = Convert.ToByte(lo);//使用Convert类转换

  

  short sh = (short)lo;       //使用强类型转换

  

  int i = int.Parse(lo.ToString());//使用类型中的Parse方法转换

  

  从上面的例子来看,我们应该很容易想到一个比较严重的问题。因为上面都是缩小转换。那么这就存在是否能够成功缩小和缩小的过程中是否会丢失资料或者损失精度。下面我们再做一个实例。步骤如下:

  

  1.在上面创建的项目"类型转换和装拆箱"中的Form1窗体上再增加一个按钮,并将按钮上的文字修改为"显示转换实例",如图2-16;

  

  2.在上面创建的项目"类型转换和装拆箱"中添加一个新的Windows窗体。在解决方案资源管理器中要添加新檔的项目名称上点击鼠标右键,选择添加新项-->添加Windows窗体'将新窗体命名为Xszh.cs。添加方式如图2-21

 

  

  图2-21

  

  小天:老田,你的解决方案自资源管理器中怎么有那么多的项目呢???我就是每次都只有一个。

  

  老田:这个简单了,你可以在vs的文件菜单中选择添加'新建项目,这样就会把新的项目添加到解决方案中了。这个就不配图了,自己摸索下。

  

  3.双击"显示转换实例"这个按钮,增加如下代码:

  

  ///<summary>

  

  ///双击"显示转换实例"按钮产生的事件,我们只是添加事件中的两行代码

  

  ///这是最后一次为自动生成的事件做注释了,以后还不明白就要罚唱征服了

  

  ///</summary>

  

  ///<param name="sender">触发事件的源</param>

  

  ///<param name="e">携带的消息</param>

  

  privatevoid button2_Click(object sender, EventArgs e)

  

  {

  

  Xszh xs = newXszh();//前面新建的Xszh窗体其实也是一个类,用的就是它

  

  xs.Show();  //显示前面新建的那个窗体

  

  }

  

  4.F5运行,试试看点击"显示转换实例"按钮,看是否会弹出新窗体。成功的话就关闭窗体,并确保VS停止调试状态了(有时候计算机反应太慢会出现,窗体已经关闭,但VS仍然处于调试状态,这样可能会导致代码只读,甚至VS报错)。如何确保呢,在VS调试状态的时候,VS默认会增加一个名为"调试"的工具条,如图2-22

 

  

  图2-22

  

  5.在Xszh窗体上点击右键->属性,修改Text属性为"显示转换实例"。

  

  小提示:由于本章是属于本书的最最最基础部分,所以我们在讲述知识的同时也很注重学习方法和Visual Studio等工具的使用说明。有基础的朋友可以快速跳过这些内容,没有基础的朋友请不要单纯的接收知识、模仿我的做法和步骤,一定要多想想,老田为什么这样来演示实例。其实我的这些过程、实例都是结合我自己的自学心得和在教学过程中很多同学容易犯错,容易忽略的地方的经验。所以相信绝对值得你认真参考。

  

  例如:向解决方案资源管理器中添加新项目、向项目中添加新项,修改控件属性、双击控件产生事件代码等等。

  

  类似修改属性的提示以后章节中也不会再提了,自己多去摸索下每个用到的控件的其它属性,都尝试下,前面讲了,在VS属性面板中对每个属性项都有说明,自己配合说明去举一反三的练习

  

  6.想窗体上分别拖出一些Label控件用于显示说明和接收转换结果。放一个TextBox用于输入要转换的数字。一个按钮,用于执行转换。一个GroupBox(在工具箱的容器分类中)。最终布局效果如图2-23

 

  

  图2-23

  

  7.双击"给我转按钮",在事件中输入下面代码:

  

  int i = int.Parse(textBox1.Text);  //因为textBox1.Text是string类型,所以必须转换

  

  //下面是将int类型分别转换,并将转换结果在转换为string类型交给对应的Label,

  

  //因为Label.Text的类型也是string,所以最终还要再转换到string后才能交给Label的Text属性

  

  //下面之所以要将(byte)i全部括起来,是因为我们要把整个i转换成byte类型后的结果ToString,

  

  //如果不将(byte)i全部括起来,那么编译器会误认为我们是要把i.ToString()强类型为byte

  

  lbl_byte.Text = ((byte)i).ToString();

  

  lbl_short.Text = ((short)i).ToString();

  

  lbl_long.Text = ((long)i).ToString();

  

  lbl_float.Text = ((float)i).ToString();

  

  lbl_double.Text = Convert.ToDouble(i).ToString();

  

  8.接着就是F5,运行程序,记得随便输入数字(是那种比较瘦的数字,不要输字符或者符号,也不要输入比较胖的那种数字,那个被认为是字符);

  

  小天:我发现我被C#忽悠了。因为他的转换结果有错,如图2-24,long和double是正确的,其它都是错误的。这咋整啊?

 

  

  图2-24

  

  嘿嘿,这就是别人说的强扭的瓜不甜。不过C#也提供了验证的方法。使用关键词checked,它可以检查数据类型转换是否安全,如果不安全,就会让运行库抛出一个溢出异常,如下:

  

  lbl_byte.Text = checked((byte)i).ToString();

  

  lbl_short.Text = checked((short)i).ToString();

  

  lbl_long.Text = checked((long)i).ToString();

  

  lbl_float.Text = checked((float)i).ToString();

  

  lbl_double.Text = checked(Convert.ToDouble(i).ToString());

  

  小天:我看double类型是可以带小数的,可是我尝试输入小数的时候就出错了。

  

  老田:所有的显式数据类型转换都可能不安全,在应用程序中应包含这样的代码,处理可能失败的数据类型转换。后面异常处理章节将使用try和 catch语句引入结构化异常处理。

  

  使用数据类型转换可以把大多数数据从一种基本类型转换为另一种基本类型。例如:给price加上0.5,再把结果转换为int:

  

  double price = 25.30;

  

  int approximatePrice = (int)(price + 0.5); //值为25,而小数点后面的0.80丢失了

  

  小天:为什么会丢失呢?

  

  老田:在这个转换过程中,小数点后面的所有数据都会丢失。因此,如果要使用这个修改过的价格进行更多的计算,最好不要使用这种转换;如果要输出全部计算完或部分计算完的近似值,且不希望用小数点后面的数据去麻烦用户,这种转换是很好的。

  

  显式数值转换用于通过显式转换表达式,将任何数字类型转换为任何其它数字类型。对于它不存在隐式转换。下表显示了这些转换。

  

  从     到

  

  sbyte     byte、ushort、uint、ulong或char

  

  byte    Sbyte或者char

  

  short    sbyte、byte、ushort、uint、ulong或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、int、uint、ulong或char

  

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

  

  char               sbyte、byte或short

  

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

  

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

  

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

  

  显示转换需要注意以下几点:

  

  显式数值转换可能导致精度损失或引发异常。

  

  将decimal值转换为整型时,该值将舍入为与零最接近的整数值。如果结果整数值超出目标类型的范围,则会引发 OverflowException。

  

  将double或float值转换为整型时,值会被截断。如果该结果整数值超出了目标值的范围,其结果将取决于溢出检查上下文。在 checked 上下文中,将引发OverflowException;而在 unchecked 上下文中,结果将是一个未指定的目标类型的值。

  

  将double转换为float时,double值将舍入为最接近的float值。如果double值因过小或过大而使目标类型无法容纳它,则结果将为零或无穷大。

  

  将float或double转换为decimal时,源值将转换为decimal表示形式,并舍入为第 28 个小数字之后最接近的数(如果需要)。根据源值的不同,可能产生以下结果:

  

  如果源值因过小而无法表示为decimal,那么结果将为零。

  

  如果源值为 NaN(非数字值)、无穷大或因过大而无法表示为decimal,则会引发OverflowException。

  

  将decimal转换为float或double时,decimal值将舍入为最接近的double或float值。

  

  要把一个可空类型转换为非可空类型,或转换为另一个可空类型,但可能会丢失数据,就必须使用显式转换。重要的是,在底层基本类型相同的元素之间进行转换时,就一定要使用显式转换,例如int?转换为int,或float?转换为float。这是因为可空类型的值可以是null,非可空类型不能表示这个值。只要可以在两个非可空类型之间进行显式转换,对应可空类型之间的显式转换就可以进行。但如果从可空类型转换为非可空类型,且变量的值是null,就会抛出InvalidOperationException。例如:

  

  int? aa = null; //让变量aa的值为null

  

  int b = (int)aa;// 会抛出异常,和MSSQL一样,C#中也认为null是未知

  

  使用显式的数据类型转换方式,并小心使用这种技术,就可以把简单值类型的任何实例转换为另一种类型。但在进行显式的类型转换时有一些限制,例如值类型,只能在数字、char类型和enum类型之间转换。不能直接把Boolean数据类型转换为其它类型,也不能把其它类型转换为Boolean数据类型。

  

  如果需要在数字和字符串之间转换,.NET类库提供了一些方法。Object类有一个ToString()方法,该方法在所有的.NET预定义类型中都进行了重写,返回对象的字符串表示:

  

  int i = 10;

  

  string s = i.ToString();

  

  如果需要分析一个字符串,获得一个数字或Boolean值,就可以使用所有预定义值类型都支持的Parse方法:

  

  string s = "100";

  

  int i = int.Parse(s);

  

  小天:看来这个转换还得多玩玩才行,只是你这样一说,我觉得还是有很多不清楚的地方。不过我觉得你上面教我的例题练习起来太痛苦了。每次运行程序后我都需要跳一个完全不用的窗体。但是我又不想为每一个例题都新建一个项目。

  

  老田:是的,多练习,多举一反三。至于你说每次都要跳一个没用的窗体这个问题,其实非常好解决,只需要在项目中的Program.cs檔里面修改启动类即可,如图2-25

 

  

  图2-25

  

  小天:这一下就清净了。我打算做10来个实例。按照上面写的那么多预定义类型挨个来试。

  

  老田:要是你挨个试了,注释也做得很清楚了,可以留下来作为以后自己随时备用的数据库。

  

  另外,再提供一个学习方法(从这个例题中你应该看出一个举一反三的思路,而不单纯是知识点描述),如下例:

  

  int a = 123;      //申明int类型变量a

  

  short b = 321;    //申明short类型变量b

  

  var c = a + b;    //让两个不同类型的变量相加

  

  Console.WriteLine(c.GetType());//混合类型的变量相加的值是什么类型呢?为什么呢?

  

  当然,如果你愿意的话,也可以将你的练习成果传到本书最后指定的学习网站,和大家一起交流心得。

  

  小提示:初学阶段,做注释其实就是进一步整理思路和加深印象的复习过程。因为你在做注释的时候,你得整理你自己学习心得,你得再次看书来印证自己的理解。只有你能够正确的把每一句代码的注释,每一段代码的思路都写出来了,这才能说明你真正的理解了这个知识点。

  

  切忌练习就是照书抄代码,抄完还不做注释。如果你是这样学习的话,我老田在这里很认真的告诉你:"你早点去学其它的吧,编程这事你做不来的"。因为你这样的做法根本学不会,你学不会其实也没啥,最重要的是你还非说我的书没有写好。

  

  本文为天轰穿原著,转载请注明出处及作者!

【上篇】
【下篇】

抱歉!评论已关闭.