📄 chapter 6.mht
字号:
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>public class zzz <o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static void Main()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>char i =3D 'A';<o:p></o:p></P>
<P class=3DCprg>short b =3D 65;<o:p></o:p></P>
<P class=3DCprg>i =3D (char)b;<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine(i);<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCoutput><U>Output</U><o:p></o:p></P>
<P class=3DCoutput>A<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">The only way out is a =
simple=20
cast. Something that was not possible implicitly is now available with a =
simple=20
cast. This is the beauty of an explicit conversion. We are going a step =
further=20
than what the implicit conversion does, hence these conversions are over =
and=20
above the implicit ones. Explicit conversions are more powerful and =
useful than=20
implicit ones. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">One more round of =
copying from=20
the documentation just to make the book complete. These are the =
conversions that=20
are available to us if and only if we use a cast. They are as follows =
verbatim.=20
Sbyte to byte, ushort, uint, ulong, or char. Byte to sbyte and char. =
Short to=20
sbyte, byte, ushort, uint, ulong, or char. Ushort to sbyte, byte, short, =
or=20
char. Int to sbyte, byte, short, ushort, uint, ulong, or char. Uint to =
sbyte,=20
byte, short, ushort, int, or char. Long to sbyte, byte, short, ushort, =
int,=20
uint, ulong, or char. Ulong to sbyte, byte, short, ushort, int, uint, =
long, or=20
char. From char to sbyte, byte, or short. Float to sbyte, byte, short, =
ushort,=20
int, uint, long, ulong, char, or decimal. Double to sbyte, byte, short, =
ushort,=20
int, uint, long, ulong, char, float, or decimal. Decimal to sbyte, byte, =
short,=20
ushort, int, uint, long, ulong, char, float, or double. =
<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">It breaks our heart =
to=20
cut-and-paste from the documentation and fill up pages of our the book. =
Do we=20
have a choice? No. Should you remember all the above rules ? Never, not =
even on=20
a rainy day!<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">Thus, we are able to =
convert from=20
one numeric type to another as they are covered by either implicit or =
explicit=20
conversions. The only way to remember the above rule is to try and =
convert one=20
numeric type to another. If we get an error then simply cast. As we are=20
permitted to convert from one type to another, we must be prepared to =
catch=20
exceptions being thrown at run time. Also, some information may be lost =
due to=20
the conversion.<SPAN style=3D"mso-spacerun: yes"> </SPAN>The =
exception gets=20
thrown depending upon the context, checked or unchecked. =
<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>public class zzz <o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static void Main()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>byte i =3D (byte)3.6;<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine(i);<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCoutput><U>Output</U><o:p></o:p></P>
<P class=3DCoutput>3<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">A float, double or =
decimal type=20
can be cast to an integer type. However, the compiler will not round off =
the=20
double to an integer but instead remove everything after the decimal =
place. The=20
documentation calls this rounding towards zero. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">By now, you must have =
realized=20
that we are reading the documentation with a fine toothcomb. It is, =
after all,=20
the last word on the C# programming language. The last word may not read =
like a=20
snazzy detective novel, but nor does our book. The more we criticize the =
documentation on grounds of legibility, readability, etc, the more we =
will sound=20
like the pot calling the kettle black. People staying in glass houses =
should not=20
throw stones and we have already thrown enough. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">Enums work the way =
for=20
conversions as expected and no point cutting more trees to explain what =
they do.=20
We honestly feel you can spend a lifetime writing C# code and yet not =
use an=20
enum ever. The Java programming language does not use enums and nobody =
misses=20
them ever. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>public class zzz <o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static void Main()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>yyy a =3D new yyy();<o:p></o:p></P>
<P class=3DCprg>xxx b =3D new xxx();<o:p></o:p></P>
<P class=3DCprg>b =3D a;<o:p></o:p></P>
<P class=3DCprg>b =3D (xxx)a;<o:p></o:p></P>
<P class=3DCprg>a =3D (yyy)b;<o:p></o:p></P>
<P class=3DCprg>a =3D b;<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>class yyy<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static implicit operator xxx( yyy =
a)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>return new xxx();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>class xxx {<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCoutput><U>Compiler Error</U><o:p></o:p></P>
<P class=3DCoutput>a.cs(9,6): error CS0030: Cannot convert type 'xxx' to =
'yyy'<o:p></o:p></P>
<P class=3DCoutput>a.cs(10,5): error CS0029: Cannot implicitly convert =
type 'xxx'=20
to 'yyy'<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">We have created a =
standard=20
implicit conversion of a yyy object to an xxx object, as usual, by using =
the=20
operator xxx. An explicit operator is not created as we can use only one =
of the=20
modifiers either implicit or explicit. However, each time we use the =
implicit=20
modifier we get a free explicit one also. Thus the line b =3D (xxx) a =
does not=20
give us any error. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">It is better to use =
an implicit=20
modifier as it also doubles up for an explicit modifier. Thus, we now =
understand=20
that when we equate a byte to an int, it is an implicit modifier as it =
works=20
with and without a cast. Alas, the reverse is not true. =
<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">We wrote a conversion =
from class=20
yyy to class xxx and not from xxx to yyy. The last two lines of main =
give us an=20
error. Nothing in life is free and thus we have to actually write the =
conversion=20
ourselves. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>public class zzz <o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static void Main()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>yyy a =3D new yyy();<o:p></o:p></P>
<P class=3DCprg>xxx b =3D new xxx();<o:p></o:p></P>
<P class=3DCprg>b =3D a;<o:p></o:p></P>
<P class=3DCprg>b =3D (xxx)a;<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>class yyy<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static explicit operator xxx( yyy =
a)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>return new xxx();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>class xxx<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCoutput><U>Compiler Error</U><o:p></o:p></P>
<P class=3DCoutput>a.cs(7,5): error CS0029: Cannot implicitly convert =
type 'yyy'=20
to 'xxx'<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">Now that we have =
asked for the=20
conversion to be explicit, the statement b =3D a will give an error. =
This is=20
because we have not used a cast and are implying a conversion. The cast =
on the=20
next line, however, passes the muster as it invokes the explicit =
operator. To=20
sum up in a sentence, the implicit conversion operator is a superset of =
the=20
explicit operator. An explicit modifier is to be used only when the =
programmer=20
is to be compelled to use a cast.<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">Conversions for the =
last time -=20
we promise.<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>public class zzz <o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static void Main()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>class yyy<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static implicit operator xxx( yyy =
a)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>return new aaa();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>class xxx<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>class aaa<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCoutput><U>Compiler Error</U><o:p></o:p></P>
<P class=3DCoutput>a.cs(11,8): error CS0029: Cannot implicitly convert =
type 'aaa'=20
to 'xxx'<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">In the above program, =
we have the=20
operator xxx that accepts one parameter, yyy, as we are in class yyy. =
This has=20
been made abundantly clear in the past. What we were vague about was the =
return=20
type. Nowhere in the world does it say that the user defined conversion =
operator=20
xxx has to return an xxx type. All that it said is that it should return =
an=20
object that can be converted to an xxx. It does not have to, we repeat =
again,=20
return an xxx object. The class aaa does not convert from an aaa object =
to an=20
xxx o
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -