100165824.htm

来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 251 行 · 第 1/5 页

HTM
251
字号
<p class="2" style="MARGIN: 0cm 0cm 8.15pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; short s = (short)I;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;// explicit</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="FONT-FAMILY: 宋体">对于预定义的数据类型,当数据类型转换可能失败或丢失某些数据时,需要显式转换。</span><span lang="EN-US">&nbsp;&nbsp;&nbsp; </span><span style="FONT-FAMILY: 宋体">例如:</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; TEXT-INDENT: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体">把</span><span lang="EN-US">int</span><span style="FONT-FAMILY: 宋体">转换为</span><span lang="EN-US">short</span><span style="FONT-FAMILY: 宋体">时,因为</span><span lang="EN-US">short</span><span style="FONT-FAMILY: 宋体">可能不够大,不能包含转换的数值。</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; TEXT-INDENT: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体">把有符号的数据转换为无符号的数据,如果有符号的变量包含一个负值,会得到不正确的结果</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; TEXT-INDENT: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="FONT-FAMILY: 宋体">在把浮点数转换为整数数据类型时,数字的小数部分会丢失。</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="FONT-FAMILY: 宋体">此时应在代码中进行显式转换,告诉编译器你知道这会有丢失数据的危险,因此编写代码时要把这种可能性考虑在内。</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">允许定义自己的数据类型</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">结构和类</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">,这意味着需要某些工具支持在自己的数据类型之间进行数据类型转换。方法是把数据类型转换定义为相关类的一个成员运算符,数据类型转换必须标记为隐式或显式,以说明如何使用它。我们应遵循与预定义数据类型转换相同的规则,如果知道无论在源变量中存储什么值,数据类型转换总是安全的,就可以把它定义为隐式转换。另一方面,如果某些数值可能会出错,例如丢失数据或抛出异常,就应把数据类型转换定义为显式转换。</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 黑体">提示:</span></p>
<p class="a1" style="MARGIN-BOTTOM: 8.15pt; TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 楷体_GB2312">如果源数据值会使数据类型转换失败,或者可能会抛出异常,就应把定制数据类型转换定义为显式转换。</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="FONT-FAMILY: 宋体">定义数据类型转换的语法类似于本章第一部分介绍的重载运算符。但它们是不一致的,数据类型转换在某种情况下可以看作是一种运算符,其作用是从源类型转换为目标类型。为了说明这个语法,下面的代码是从本节后面介绍的示例中节选的:</span></p>
<p class="2" style="MARGIN: 8.15pt 0cm 0pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">public static implicit operator float (Currency value)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp; // processing</span></p>
<p class="2" style="MARGIN: 0cm 0cm 8.15pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">}</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="FONT-FAMILY: 宋体">运算符的返回类型定义了数据类型转换操作的目标类型。这里定义的数据类型转换可以隐式地把</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">的值转换为</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 宋体">型。注意,如果数据类型转换声明为隐式,编译器可以隐式或显式地使用这个转换。如果数据类型转换声明为显式,编译器就只能显式地使用转换。其他运算符重载一样,数据类型转换必须声明为</span><span lang="EN-US">public</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">static</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 黑体">注意:</span></p>
<p class="a1" style="MARGIN-BOTTOM: 8.15pt; TEXT-INDENT: 21.45pt"><span lang="EN-US">C++</span><span style="FONT-FAMILY: 楷体_GB2312">开发人员应注意,这种情况与</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 楷体_GB2312">是不同的,在</span><span lang="EN-US">C++</span><span style="FONT-FAMILY: 楷体_GB2312">中,数据类型转换是类的成员</span><span lang="EN-US">&nbsp;&nbsp;&nbsp; </span><span style="FONT-FAMILY: 楷体_GB2312">实例。</span></p>
<h3 style="MARGIN: 8.15pt 0cm"><span><span lang="EN-US">5.5.1 &nbsp;</span></span><span style="FONT-FAMILY: 黑体">执行用户定义的类型转换</span></h3>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span><span style="FONT-FAMILY: 宋体">本节将在示例</span><span lang="EN-US">SimpleCurrency(</span></span><span style="FONT-FAMILY: 宋体">和往常一样,其代码可以下载</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">中介绍隐式和显式使用用户定义的数据类型转换。在这个示例中,定义一个结构</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">,它包含一个正的</span><span lang="EN-US">US$</span><span style="FONT-FAMILY: 宋体">钱款。</span><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">为此提供了</span><span lang="EN-US">decimal</span><span style="FONT-FAMILY: 宋体">类型,但如果要进行比较复杂的财务处理,仍可以编写自己的结构和类来表示钱款,在这样的类上执行特定的方法。</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 黑体">注意:</span></p>
<p class="a1" style="MARGIN-BOTTOM: 8.15pt; TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 楷体_GB2312">数据类型转换的语法对于结构和类是一样的。我们的示例定义了一个结构,但如果把</span><span lang="EN-US">Currency </span><span style="FONT-FAMILY: 楷体_GB2312">声明为类,也是可以的。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">首先,结构</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">的定义如下所示。</span></p>
<p class="2" style="MARGIN: 8.15pt 0cm 0pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; struct Currency</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp; {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public uint Dollars;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ushort Cents;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Currency(uint dollars, ushort cents)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Dollars = dollars;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.Cents = cents;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override string ToString()</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt; LINE-HEIGHT: 15pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return string.Format(&quot;${0}.{1,</span><span style="FONT-FAMILY: 宋体">&ndash;</span><span lang="EN-US">2:00}&quot;, Dollars,Cents);</span></p>
<p class="2" style="MARGIN: 0cm 0cm 8.15pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal"><span lang="EN-US">Dollars</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">Cents</span><span style="FONT-FAMILY: 宋体">字段使用无符号的数据类型,可以确保</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">实例只能包含正值。这样限制,是为了在后面说明显式转换的一些要点。可以像这样使用一个类来存储公司员工的薪水信息。人们的薪水不会是负值!为了使类比较简单,我们把字段声明为</span><span lang="EN-US">public</span><span style="FONT-FAMILY: 宋体">,但通常应把它们声明为</span><span lang="EN-US">private</span><span style="FONT-FAMILY: 宋体">,并为</span><span lang="EN-US">Dollars</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">Cents</span><span style="FONT-FAMILY: 宋体">字段定义相应的属性。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">下面先假定要把</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">实例转换为</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 宋体">值,其中</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 宋体">值的整数部分表示美元,换言之,应编写下面的代码:</span></p>
<p class="2" style="MARGIN: 8.15pt 0cm 0pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; Currency balance = new Currency(10,50);</span></p>
<p class="2" style="MARGIN: 0cm 0cm 8.15pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp; float f = balance; // We want f to be set to 10.5</span></p>
<p class="MsoNormal" style="TEXT-INDENT: 0cm"><span style="FONT-FAMILY: 宋体">为此,需要定义一个数据类型转换。给</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">定义添加下述代码:</span></p>
<p class="2" style="MARGIN: 8.15pt 0cm 0pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static implicit operator float (Currency value)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return value.Dollars + (value.Cents/100.0f);</span></p>
<p class="2" style="MARGIN: 0cm 0cm 8.15pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这个数据类型转换是隐式的。在本例中这是一个合理的选择,因为在</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">定义中,这应是很清晰的,可以存储在</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">中的值也都可以存储在</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 宋体">中。在这个转换中,不应出现任何错误。</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 黑体">注意:</span></p>
<p class="a1" style="MARGIN-BOTTOM: 8.15pt; TEXT-INDENT: 21.45pt"><span style="FONT-FAMILY: 楷体_GB2312">这里有一点欺骗性</span><span lang="EN-US">:</span><span style="FONT-FAMILY: 楷体_GB2312">实际上,当把</span><span lang="EN-US">uint</span><span style="FONT-FAMILY: 楷体_GB2312">转换为</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 楷体_GB2312">时,就会有精确度的损失,但</span><span lang="EN-US">Microsoft</span><span style="FONT-FAMILY: 楷体_GB2312">认为这种错误并不重要,因此把从</span><span lang="EN-US">uint</span><span style="FONT-FAMILY: 楷体_GB2312">到</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 楷体_GB2312">的转换都当做隐式转换。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">但是,如果把一个浮点数</span><span lang="EN-US">(float)</span><span style="FONT-FAMILY: 宋体">转换为货币值,就不能保证转换肯定能成功了;</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 宋体">可以存储负值,而</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">实例不能,</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 宋体">存储的数值的量级要比</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">的</span><span lang="EN-US">(uint) Dollars</span><span style="FONT-FAMILY: 宋体">字段大得多。所以,如果</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 宋体">包含一个不合适的值,把它转换为</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">就会得到意想不到的结果。因此,从</span><span lang="EN-US">float</span><span style="FONT-FAMILY: 宋体">转换到</span><span lang="EN-US">Currency</span><span style="FONT-FAMILY: 宋体">就应定义为显式转换。下面是我们的第一次尝试,这次不会得到正确的结果,但对第一次尝试是有帮助的:</span></p>
<p class="2" style="MARGIN: 8.15pt 0cm 0pt 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static explicit operator Currency (float value)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; TEXT-INDENT: 18.45pt"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?