📄 chapter 6.mht
字号:
<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(13,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">We believe the above =
is a special=20
case. Here we are returning an aaa object instead of xxx.<SPAN=20
style=3D"mso-spacerun: yes"> </SPAN>The compiler tries to convert =
the aaa=20
object to an xxx object and realizes there is no such conversion =
possible in=20
class yyy. Hence, the error. To remove the error, place an operator xxx =
in class=20
aaa, which will convert the aaa object into an xxx like object. It will =
make an=20
exception only if the return type is the same class that the code =
resides in. We=20
yet are firm in our belief that someone somewhere goofed up.=20
<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><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></U></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>class yyy {<o:p></o:p></P>
<P class=3DCprg>public static implicit operator yyy(yyy =
b)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>return new yyy();<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(3,15): error CS0555: User-defined operator =
cannot take an=20
object of the enclosing type and convert to an object of the enclosing=20
type<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">Thus we can only =
convert from one=20
type to another and not to the same type again. It does not make any =
sense even=20
to a madman why we would like to take a yyy object and convert it back =
again to=20
a yyy object. Also, these conversion operators must lie in the same =
class and=20
not in any other class.<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>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>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<SPAN style=3D"mso-spacerun: yes"> =20
</SPAN><o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static implicit operator xxx (yyy =
b)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("op xxx");<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>public static implicit operator yyy (xxx =
b)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("op yyy");<o:p></o:p></P>
<P class=3DCprg>return new yyy();<o:p></o:p></P>
<P class=3DCprg>} <o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P=20
class=3DCoutput><U><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></U></P>
<P class=3DCoutput><U>Output</U><o:p></o:p></P>
<P class=3DCoutput>op xxx<o:p></o:p></P>
<P class=3DCoutput>op 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">The code to convert =
an xxx object=20
to a yyy must reside in the class yyy only. If we create such an =
operator, it=20
will work on a=3Db, as the xxx object b can now be converted into a yyy =
like=20
object. However, b =3D a will give an error unless we have an impicit =
operator yyy=20
in class xxx. If there is no such conversion available in class xxx to =
convert a=20
yyy object to an xxx object, a compiler error is generated. This =
conversion=20
cannot reside in yyy or any other class, it has to be in the xxx class=20
only.<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>public static void Main() {<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>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<SPAN style=3D"mso-spacerun: yes"> =20
</SPAN><o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static implicit operator xxx (yyy =
b)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("op xxx");<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>public static implicit operator yyy (xxx =
b)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("op yyy");<o:p></o:p></P>
<P class=3DCprg>return new yyy();<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=3DCoutput><U>Output</U><o:p></o:p></P>
<P class=3DCoutput>op xxx<o:p></o:p></P>
<P class=3DCoutput>op 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">Should we apologize =
to the=20
compiler? No. Did we lead you up the garden path? No. Every language has =
certain=20
quirks. We want to convert a yyy object to an xxx object and vice versa. =
C# felt=20
it to be too cumbersome to write the code in two separate classes. So it =
made a=20
one time exception to all its rules. You can have a conversion operator =
take a=20
single parameter other than the class data type. We have thus broken one =
golden=20
rule in operator yyy within class yyy. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">Class yyy contains a =
function=20
that accepts one parameter, not a yyy object but an xxx object. The code =
is much=20
more compact where logically relevant code is place together.=20
<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">Remember there is =
always a method=20
behind the madness and at times breaking rules makes the world go round=20
better.<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>class yyy {<o:p></o:p></P>
<P class=3DCprg>public static implicit operator xxx (yyy =
b)<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>interface 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(3,15): error CS0552: 'yyy.implicit operator =
xxx(yyy)':=20
user-defined conversion to/from interface<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 cannot convert to =
and from an=20
interface. The above restriction is due to the fact that an interface =
and a=20
class differ in concept. A class has code whereas an interface doesn't. =
Similar=20
to water and oil that do not mix and match, we cannot convert from two =
differing=20
concepts.<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"><![if =
!supportEmptyParas]><![endif]> <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>class yyy<SPAN style=3D"mso-spacerun: yes"> =
</SPAN>:=20
xxx<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static implicit operator xxx (yyy =
b)<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(3,15): error CS0553: 'yyy.implicit operator =
xxx(yyy)':=20
user-defined conversion to/from base class<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">An object that looks =
like yyy=20
also looks like xxx as yyy is derived from xxx. Thus there is already a =
way for=20
a yyy object to scale down and become an xxx object. This is built in =
the=20
inheritance structure. We do not need an operator to do what already =
happens by=20
default. <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">Converting to a base =
class is an=20
error as we try to duplicate what the compiler has already done for us. =
In the=20
same vein, we cannot convert to an object as the Object class is the =
base class=20
for all classes. All classes implicitly convert to an Object class and =
these=20
conversions are already predefined. We are also not allowed to override =
a=20
predefined conversion. The signature of the operator is its name, return =
type=20
and parameter type. Unlike operators, the return type is part of the =
signature.=20
The keyword implicit and explicit are not part of the=20
signature.<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>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>class yyy<SPAN style=3D"mso-spacerun: yes"> =20
</SPAN><o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static implicit operator xxx (yyy =
b)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>throw new System.Exception();<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>Output</U><o:p></o:p></P>
<P class=3DCoutput>Exception occurred: System.Exception: An exception of =
type=20
System.Exception was thrown.<o:p></o:p></P>
<P class=3DCoutput><SPAN style=3D"mso-spacerun: yes"> =
</SPAN>at=20
yyy.op_Implicit(yyy b)<o:p></o:p></P>
<P class=3DCoutput><SPAN style=3D"mso-spacerun: yes"> =
</SPAN>at=20
zzz.Main()<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 user-defined =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -