仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 619|回复: 9
打印 上一主题 下一主题

[学习教程] NET网页编程之C#托付进修(三):托付链—同时托付多个办法

[复制链接]
再现理想 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 14:20:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
如果英语好,口才好,加上女孩子的优势说不定有机会进去做做别的工具)上一节中先容了下编译器是怎样来翻译托付的,从两头言语的角度往看托付,但愿能够匡助人人进一步的了解托付,但是之前的先容都是托付只是封装一个办法,那托付能不克不及封装多个办法呢?由于生存中常常会听到,我代表人人的定见等如许的措辞,既然托付也是一个代表,那他假如只能代表一团体,那他的魅力就不是很年夜了吧,以是我们就会托付能不克不及代表多个办法的?谜底是能够的,这就是本节要讲的内容——托付链,托付链也是一个托付,只是由于它是把多个托付链在一同,以是我们就以托付链来这么称号它的。

1、究竟甚么是托付链
我们寻常实例化托付工具时都是绑定一个办法的,前一个专题先容的托付也是包装了一个办法的,用后面的例子就是委派状师的只要一团体,也就是当事人只要一个的,可是实际生存中明显不是如许的,在讼事的时分状师能够同时接多个案子,也是吸收多个事先人的委派,如许,该状师就与多个当事人绑定在一同了,必要懂得多个当事人的案件情形的。实在这就是生存中的托付链,此时这位状师不单单是一团体的代表状师了,而是多个当事人的状师。生存中的托付链和C#中的托付链很相似的,如今就说说C#中的托付链究竟是个甚么的?

起首托付链就是一个托付,以是人人不要看到托付链感到又是甚么C#中的新特征的,但是要把多个托付链在一同,就必需存储多个托付的援用,那托付链工具是在那里存储多个托付的援用的呢?还记得我们上一专题中,我们先容的托付范例有三个非大众字段的吗?这三个字段是——_target,methodPtr和_invocationList,至于这三个字段详细代表甚么人人能够检察我的上一专题的文章,但是_invocationList字段恰是存储多个托付援用的中央的。

为了更好的注释_invocationList是怎样来存储托付援用的,上面先看一个托付链的例子和运转了局,然后再剖析缘故原由:
usingSystem;

namespaceDelegateTest
{
publicclassProgram
{
//声明一个托付范例,它的实例援用一个办法
//该办法归去一个int参数,前往void范例
publicdelegatevoidDelegateTest(intparm);

publicstaticvoidMain(string[]args)
{
//用静态办法来实例化托付
DelegateTestdtstatic=newDelegateTest(Program.method1);

//用实例办法来实例化托付
DelegateTestdtinstance=newDelegateTest(newProgram().method2);

//隐式挪用托付
dtstatic(1);

//显式挪用Invoke办法来挪用托付
dtinstance.Invoke(1);

//隐式挪用托付
dtstatic(2);

//显式挪用Invoke办法来挪用托付
dtinstance.Invoke(2);
Console.Read();
}
privatestaticvoidmethod1(intparm)
{
Console.WriteLine("挪用的是静态办法,参数值为:"+parm);
}

privatevoidmethod2(intparm)
{
Console.WriteLine("挪用的是实例办法,参数值为:"+parm);
}
}
}

运转了局:


上面就来剖析下为何会呈现如许的了局的:

一入手下手我们实例化了两个托付变量,以下代码:
//用静态办法来实例化托付
DelegateTestdtstatic=newDelegateTest(Program.method1);

//用实例办法来实例化托付
DelegateTestdtinstance=newDelegateTest(newProgram().method2);

托付变量dtstatic和dtinstance援用的托付工具的初始形态以下图:


然后我们界说了一个托付范例的援用变量delegatechain,刚入手下手它没有任何托付工具,是一个空援用,当我们实行上面的一行代码时:
delegatechain=(DelegateTest)Delegate.Combine(delegatechain,dtstatic);

Combine办法发明试图兼并的是null和dtstatic,在外部,Combine间接前往dtstatic中的工具,此时delegatechain和dtstatic变量援用的都是统一个托付工具,以下图所示:


为了演示托付链,我们经由过程代码在再增加一个托付,此时就再挪用了Combine办法,代码以下:
delegatechain=(DelegateTest)Delegate.Combine(delegatechain,dtinstance);

这时候候,Combine办法发明delegatechain已援用了一个托付工具了(此时已援用了destatic援用的托付工具了),以是Combine会机关一个新的托付工具(这一点很想String.Concat,我们复杂的利用是经由过程+操纵符把两个字符串联接起来,这个新的托付工具会对它的公有字段_target和_methodPtr字段举行初始化,然后此时_invocationList字段初始化为援用了一个托付工具的数组,这个数组的第一个元素(下标为0)就是被初始化为援用包装了method1办法的托付,数组的二个元素被初始化为援用包装了method2办法的托付(也就是dtinstance援用的托付工具),最初delegaechain被设为援用新建的这个托付工具,上面是一个图,能够匡助人人了解托付链(也叫多播托付):


一样的事理,假如是增加第三个托付给托付链,历程也是和下面一样的,此时又会新建一个托付工具,此时_invocationList字段会初始化为援用一个保留这三个托付工具数组,但是有人会问了——关于已援用了托付工具的托付范例变量挪用Combine办法后会创立一个新的托付工具,然后对新的这个托付工具的三个字段举行从头初始化话,最初把之前的托付范例变量援用新创立的托付工具(这里就帮人人总结下托付链的创立历程),那之前的托付工具怎样办呢?信任年夜部分人会有这个疑问的,这点和字符串的Concat办法很像,之前的托付工具和——invocationList字段援用的数组会被渣滓接纳失落(恰是由于如许,托付和字符串String一样是不成变的)。

注重:我们还能够挪用Delegate的Remove办法从链中删除托付,如挪用上面代码时:
delegatechain=(DelegateTest)Delegate.Remove(delegatechain,newDelegateTest(method1));Remove

办法被挪用时,它会扫描delegateChain(第一个参数)所援用的托付工具外部保护的托付数组(假如关于托付数组为空的情形下挪用Remove办法将不会有任何感化,就是不会删除任何托付援用,这里次要是申明扫描是从托付数组里举行扫描),假如找到delegateChain援用的托付工具的_target和_methodPtr字段和第二个参数(新创立的托付)中的字段婚配的托付,假如删除以后数组中只剩下一个数据项时,就前往谁人数据项(而不会往新建一个托付工具再初始化的,此时的_invocationList为null,而不是保留一个托付工具援用的数组了,详细能够Remove一个后调试看看的),假如此时数组中还残剩多个数据项,就新建一个托付工具——个中创立并初始化_invocationList数组(此时的数组援用的托付工具已少了一个了,由于用Remove办法删除),而且,每次Remove办法挪用只能从链中删除一个托付,而不会删除有婚配的_target和_methodPtr字段的一切托付(这个人人能够调试看看的)。

2、怎样对托付链中的托付挪用举行把持
经由过程下面信任人人能够了解怎样创立一个托付链工具的,可是从运转了局中还能够看出,每次挪用托付链时,托付链包装的每一个办法城市按次被实行,假如托付链中被挪用的托付抛出一个非常,如许链中的后续一切工具都不克不及被挪用,而且假如托付的后面具有一个非void的前往范例,则只要最初一个前往值会被保存,其他一切回调办法的前往值城市被舍弃,这就意味着其他一切操纵的前往值都永久看不到的吗?现实却不是如许的,我们能够经由过程挪用Delegate.GetInvocationList办法来显式挪用链中的每个托付,同时能够增加一些本人的界说输入。

GetInvocationList办法前往一个由Delegate援用组成的数组,个中每个数组都指向链中的一个托付工具。在外部,GetInvocationList创立并初始化一个数组,让数据的每个元素都援用链中的一个托付,然后前往对该数组的一个援用。假如_invocatinList字段为null,前往的数组只要一个元素,该元素就是托付实例自己。上面就经由过程一个程序来演示下的:
namespaceDelegateChainDemo
{
classProgram
{
//声明一个托付范例,它的实例援用一个办法
//该办法归去一个int参数,前往void范例
publicdelegatestringDelegateTest();

staticvoidMain(string[]args)
{
//用静态办法来实例化托付
DelegateTestdtstatic=newDelegateTest(Program.method1);

//用实例办法来实例化托付
DelegateTestdtinstance=newDelegateTest(newProgram().method2);
DelegateTestdtinstance2=newDelegateTest(newProgram().method3);
//界说一个托付链工具,一入手下手初始化为null,就是不代表任何办法(我就是我,我不代表任何人)
DelegateTestdelegatechain=null;
delegatechain+=dtstatic;
delegatechain+=dtinstance;
delegatechain+=dtinstance2;

////delegatechain=(DelegateTest)Delegate.Remove(delegatechain,newDelegateTest(method1));
////delegatechain=(DelegateTest)Delegate.Remove(delegatechain,newDelegateTest(newProgram().method2));
Console.WriteLine(Test(delegatechain));
Console.Read();
}

privatestaticstringmethod1()
{
return"这是静态办法1";
}

privatestringmethod2()
{
thrownewException("抛出了一个非常");
}

privatestringmethod3()
{
return"这是实例办法3";
}
//测试挪用托付的办法
privatestaticstringTest(DelegateTestchain)
{
if(chain==null)
{
returnnull;
}

//用这个变量来保留输入的字符串
StringBuilderreturnstring=newStringBuilder();

//猎取一个托付数组,个中每一个元素都援用链中的托付
Delegate[]delegatearray=chain.GetInvocationList();

//遍历数组中的每一个托付
foreach(DelegateTesttindelegatearray)
{
try
{
//挪用托付取得前往值
returnstring.Append(t()+Environment.NewLine);
}
catch(Exceptione)
{
returnstring.AppendFormat("非常从{0}办法中抛出,非常信息为:{1}{2}",t.Method.Name,e.Message,Environment.NewLine);
}
}

//把了局前往给挪用者
returnreturnstring.ToString();
}
}
}

运转了局截图:


从运转了局能够看出,此时我们能够取得每个回调办法的前往值,而且能够到场一些自界说的前往值的(程序中到场了换行字符串),如许就能够对托付链中的每一个托付工具举行把持了,即便个中一个抛出非常,此时我们也能够举行捕捉,而不会招致后续的托付工具不克不及被挪用的成绩。

3、总结
本专题次要先容怎样创立一个托付链和关于创立一个托付链的历程举行了具体的分享,第二部分次要先指出了托付了一些范围性,然后经由过程挪用GetInvocationList办法来前往一个托付数组,如许就能够经由过程遍历托付数组中的每一个托付来关照托付的挪用历程,如许就能够对托付链的挪用举行更多的把持的。到此本专题也就先容完了,经由过程这三个专题对托付的先容,信任人人会对托付有一个更深的了解。前几天同学问我学习方向的问题。有点想法,不知道对不对,怕误导同学,现在“开源一下”。注:括号内是我现在整理的时填加上的。
不帅 该用户已被删除
沙发
发表于 2015-1-18 13:01:03 | 只看该作者
asp.net空间的支持有:ASP.NET1.1/虚拟目录/MicrosoftFrontPage2000扩展/CDONTS,同时他的网站上也提供了Asp.net的使用详解和程序源代码,相信对使用ASP.NET编程的程序员来说会非常有用哦!
愤怒的大鸟 该用户已被删除
板凳
发表于 2015-1-18 13:01:03 | 只看该作者
主流网站开发语言之PHPHP的全名非常有趣,它是一个巢状的缩写名称——“PHP:HypertextPreprocessor”,打开缩写还是缩写。PHP是一种HTML内嵌式的语言(就像上面讲的ASP那样)。而PHP独特的语法混合了C,Java,Perl以及PHP式的新语法。它可以比CGI或者Perl更快速地执行动态网页。
只想知道 该用户已被删除
地板
发表于 2015-1-26 14:06:49 | 只看该作者
在一个项目中谁敢保证每天几千万甚至几亿条的数据不丢失?谁敢保证应用的高可靠性?有可以借签的项目吗?
柔情似水 该用户已被删除
5#
发表于 2015-2-4 20:05:33 | 只看该作者
以上是语言本身的弱点,在功能方面ASP同样存在问题,第一是功能太弱,一些底层操作只能通过组件来完成,在这点上是远远比不上PHP/JSP,其次就是缺乏完善的纠错/调试功能,这点上ASP/PHP/JSP差不多。
爱飞 该用户已被删除
6#
发表于 2015-2-10 06:26:33 | 只看该作者
在一个项目中谁敢保证每天几千万甚至几亿条的数据不丢失?谁敢保证应用的高可靠性?有可以借签的项目吗?
变相怪杰 该用户已被删除
7#
发表于 2015-3-1 01:36:35 | 只看该作者
是指转换后的Servlet程序代码的行数。这给调试代码带来一定困难。所以,在排除错误时,可以采取分段排除的方法(在可能出错的代码前后输出一些字符串,用字符串是否被输出来确定代码段从哪里开始出错)。
小妖女 该用户已被删除
8#
发表于 2015-3-10 12:28:19 | 只看该作者
关于ASP.NET功能上,ASP.NET比微软以前的ASP(96年出现)有更强大的library,更好的稳定性。ASP.NET可以使用.NETFramework中所有组件(也就是说.NET能实现的,ASP.NET一样能实现)。
透明 该用户已被删除
9#
发表于 2015-3-17 07:11:03 | 只看该作者
逐步缩小出错代码段的范围,最终确定错误代码的位置。
再见西城 该用户已被删除
10#
发表于 2015-3-24 02:11:52 | 只看该作者
微软又推出ASP.NET。这不是ASP的简单升级,而是全新一代的动态网页实现系统,用于一台WEB服务器建立强大的应用程序。是微软发展的新体系结构.NET的一部分,是ASP和.NET技术的结合。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-18 06:29

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表