📄 chapter 5.mht
字号:
pqr(pqr1);<o:p></o:p></P>
<P class=3DCprg>pqr e<SPAN style=3D"mso-spacerun: yes"> </SPAN>=3D =
new=20
pqr(pqr1);<o:p></o:p></P>
<P class=3DCprg>pqr f =3D d + e;<o:p></o:p></P>
<P class=3DCprg>int k;<o:p></o:p></P>
<P class=3DCprg>f(out k);<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>pqr1<o:p></o:p></P>
<P class=3DCoutput>pqr1<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">Aha! A delegate =
function can=20
accept output parameters. Hence we see the output displayed as=20
pqr1.<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>aa a =3D new aa();<o:p></o:p></P>
<P class=3DCprg>a.abc();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>public delegate int pqr(out int i);<o:p></o:p></P>
<P class=3DCprg>public class aa<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>int pqr1 (out int i)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>i =3D 10;<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("pqr1 " + i); <o:p></o:p></P>
<P class=3DCprg>return 0;<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>public void abc()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>pqr d<SPAN style=3D"mso-spacerun: yes"> </SPAN>=3D =
new=20
pqr(pqr1);<o:p></o:p></P>
<P class=3DCprg>pqr e =3D null; <o:p></o:p></P>
<P class=3DCprg>pqr f =3D d + e;<o:p></o:p></P>
<P class=3DCprg>int k;<o:p></o:p></P>
<P class=3DCprg>f(out k);<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>pqr1 10<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 same program now =
works. The=20
only change made is we have initialized one of the delegates to null. =
Now the=20
rules of simple delegates come into play. The rules of multi-cast =
delegates are=20
more restrictive. This also proves the hypothesis that multi-cast =
delegates are=20
not part of the programming language as the compiler did not catch the =
error. As=20
the compiler ignored it, it means that it is not part and parcel of the =
language=20
definition. <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">System.Delegate =
introduces a lot=20
of extra code in the delegate. It is this code that actually performs =
error=20
checks and if we break any rules it throws an error at run time. The =
next=20
version of System.Delegate and not C# may handle these errors=20
gracefully.<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">Two different =
delegates can refer=20
to the same method and target object. The plus operator thus lets you =
combine=20
delegates and the subtraction operator lets you remove one delegate from =
another. We do have to stop at two delegates only. When we execute a =
multi-cast=20
delegate, the effect is similar when invoking an ordered list of =
non-multicast=20
delegates. <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>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>aa a =3D new aa();<o:p></o:p></P>
<P class=3DCprg>try<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>a.abc();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>catch ( System.Exception e)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("in 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>public delegate void pqr();<o:p></o:p></P>
<P class=3DCprg>public class aa<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>void pqr1()<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>}<o:p></o:p></P>
<P class=3DCprg>public void abc()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>pqr d<SPAN style=3D"mso-spacerun: yes"> </SPAN>=3D =
new=20
pqr(pqr1);<o:p></o:p></P>
<P class=3DCprg>d();<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>in 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">In the above program, =
d() calls=20
function pqr1. This function throws an exception. We could have caught =
the=20
exception using try catch in function abc itself but we chose not to do =
so.=20
Instead, we catch it in main where abc is called. The exception thrown =
in the=20
function called by the delegate moves up the ladder until it finally is =
caught.=20
If the catch clause is ignored, it generates a run time error as=20
below.<o:p></o:p></SPAN></P>
<P=20
class=3DCoutput><U><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></U></P>
<P class=3DCoutput><U>Ouput</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
aa.pqr1()<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=3DCoutput><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></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>aa a =3D new aa();<o:p></o:p></P>
<P class=3DCprg>a.abc();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>public delegate void pqr(ref int i);<o:p></o:p></P>
<P class=3DCprg>public class aa<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>void pqr1 (ref int i)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>i =3D i + 2;<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("pqr1 " + i); <o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>public void abc()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>pqr d =3D new pqr(pqr1);<o:p></o:p></P>
<P class=3DCprg>pqr e =3D new pqr(pqr1);<o:p></o:p></P>
<P class=3DCprg>pqr f =3D d + e;<o:p></o:p></P>
<P class=3DCprg>int k =3D 3;<o:p></o:p></P>
<P class=3DCprg>f(ref k);<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>pqr1 5<o:p></o:p></P>
<P class=3DCoutput>pqr1 7<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">Earlier, we discussed =
about the=20
out parameters and concluded that they are not allowed in a multicast =
delegate.=20
Conversely, passing by ref is permissible in multi-cast delegate =
invocations. If=20
the called function changes k, the change is transmitted straight =
through. Thus=20
every invocation of pqr1 refers to the same variable k each=20
time.<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>aa a =3D new aa();<o:p></o:p></P>
<P class=3DCprg>a.abc();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>public delegate void pqr();<o:p></o:p></P>
<P class=3DCprg>public class aa<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public void pqr1()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("pqr1");<o:p></o:p></P>
<P class=3DCprg>throw new System.Exception();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>public void pqr2()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("pqr2");<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>public void abc()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>pqr d<SPAN style=3D"mso-spacerun: yes"> </SPAN>=3D =
new=20
pqr(pqr1);<o:p></o:p></P>
<P class=3DCprg>pqr e<SPAN style=3D"mso-spacerun: yes"> </SPAN>=3D =
new=20
pqr(pqr2);<o:p></o:p></P>
<P class=3DCprg>pqr f<SPAN style=3D"mso-spacerun: yes"> </SPAN>=3D =
d+e;<o:p></o:p></P>
<P class=3DCprg>f();<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>pqr1<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>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
aa.pqr1()<o:p></o:p></P>
<P class=3DCoutput><SPAN style=3D"mso-spacerun: yes"> =
</SPAN>at=20
pqr.Invoke()<o:p></o:p></P>
<P class=3DCoutput><SPAN style=3D"mso-spacerun: yes"> =
</SPAN>at=20
aa.abc()<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">If an exception is =
thrown during=20
a multi-delegate invocation, no more code gets called, processing simply =
halts.=20
Everything comes to a standstill. The function pqr1 gets called first. =
As it=20
throws an exception, C# does not call function pqr2, that it was =
supposed to=20
after finishing with function pqr1.<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>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>aa a =3D new aa();<o:p></o:p></P>
<P class=3DCprg>a.abc();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>public delegate void pqr();<o:p></o:p></P>
<P class=3DCprg>public class aa<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>void pqr1 ()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine("pqr1"); <o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>public void abc()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>pqr d =3D new pqr(pqr1);<o:p></o:p></P>
<P class=3DCprg>bb b =3D new bb();<o:p></o:p></P>
<P class=3DCprg>pqr e =3D new pqr(b.xyz);<o:p></o:p></P>
<P class=3DCprg>pqr f =3D d + e;<o:p></o:p></P>
<P class=3DCprg>f();<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -