柔情似水 发表于 2015-1-16 22:34:59

ASP.NET网页设计座谈C#编程中的多态与new关头字

兄弟们,想来你们都看过了昨天的比赛了。我现在的痛苦状跟当时应该差不多。希望本版.net老师不吝赐教,为小弟这一批迷途的羊羔指一条阳光之道!您也知道:学习技术如果只有一个人摸索,那是一件多么痛苦的事情!还有,如果万辛能得名师或长者指点,那又是多么一件幸福和快乐的事情!编程|关头字  1.你一般如何用多态?

  假定我有一个类,内里有一个PrintStatus办法,用于打印实例确当前形态,我但愿该类的派生类都带有一个PrintStatus办法,而且这些办法都用于打印实在例确当前形态。那末我会如许表达我的希望:

//Code#01

classBase
{
 publicvirtualvoidPrintStatus()
 {
  Console.WriteLine("publicvirtualvoidPrintStatus()inBase");
 }
}
  因而我能够写一个如许的办法:

//Code#02

publicvoidDisplayStatusOf(Base[]bs)
{
 foreach(Basebinbs)
 {
  b.PrintStatus();
 }
}
  bs中大概包括着分歧的Base的派生类,但我们却能够疏忽这些“本性”而利用一种一致的体例来处置某事。在.NET2.0中,XmlReader的Create有如许一个版本:

publicstaticXmlReaderCreate(Streaminput);
  你能够向Create传送任何可用的“流”,比方来自文件的“流”(FileStream)、来自内存的“流”(MemoryStream)或来自收集的“流”(NetworkStream)等。固然每中“流”的事情细节都分歧,但我们却利用一种一致的体例来处置这些“流”。

  2.假设有人不恪守答应...

  DisplayStatusOf隐含着如许一个假定:bs中假如存在派生类的实例,那末该派生类应当重写PrintStatus,固然必需加上override关头字:

//Code#03

classDerived1:Base
{
 publicoverridevoidPrintStatus()
 {
  Console.WriteLine("publicoverridevoidPrintStatus()inDerived1");
 }
}
  你能够把这看做一种答应、商定,直到有人沉不住气...

//Code#04

classDerived2:Base
{
 publicnewvoidPrintStatus()
 {
  Console.WriteLine("publicnewvoidPrintStatus()inDerived2");
 }
}
  假定我们有如许一个数组://Code#05

Base[]bs=newBase[]
{
 newBase(),
 newDerived1(),
 newDerived2()
};
  把它传送给DisplayStatusOf,则输入是:

//Output#01

//publicvirtualvoidPrintStatus()inBase
//publicoverridevoidPrintStatus()inDerived1
//publicvirtualvoidPrintStatus()inBase
  从输入了局中很简单看出Derived2并没有依照我们希冀的往做。但你无需惊奇,这是因为Derived2的计划者没有“恪守商定”的原因。

  3.new:封印咒术

  new仿佛给人一种如许的感到,它的利用者喜好冲破他人的商定,但是,假如利用得当,new能够填补基类计划者的“短见”。在CreatingaDataBoundListViewControl中,RockfordLhotka就树模了怎样封印本来的ListView.Columns,并使自行增加的前往DataColumnHeaderCollection的Columns取而代之。

  从Output#01中我们能够看到,new只是把Base.PrintStatus封印起来而不是没落失落,你能够排除封印然落后行会见。关于Derived2的利用者,解封的办法是把Derived2的实例转换成Base范例:

//Code#06

Based2=newDerived2();
d2.PrintStatus();

//Output#02

//publicvirtualvoidPrintStatus()inBase
而在Derived2外部,你能够透过base来会见:

//Code#07

base.PrintStatus();
  这类办法是针对实例成员的,假如被封印的成员是静态成员的话,就要透过类名来会见了。

  4.假设Base.PrintStatus是某个接口的隐式完成...

  假设Base完成了一个IFace接口:

//Code#08

interfaceIFace
{
 voidPrintStatus();
}

classBase:IFace
{
 publicvirtualvoidPrintStatus()
 {
  Console.WriteLine("publicvirtualvoidPrintStatus()inBase");
 }
}
  我们只必要让Derived2从头完成IFace:

//Code#09

classDerived2:Base,IFace
{
 publicnewvoidPrintStatus()
 {
  Console.WriteLine("publicnewvoidPrintStatus()inDerived2");
 }
}
  Derived1坚持稳定。则把:

//Code#10

IFace[]fs=newIFace[]
{
 newBase(),
 newDerived1(),
 newDerived2(),
}
  传送给:

//Code#11

publicvoidDisplayStatusOf(IFace[]fs)
{
 foreach(IFacefinfs)
 {
  f.PrintStatus();
 }
}
  输入了局是:

//Output#03

//publicvirtualvoidPrintStatus()inBase
//publicoverridevoidPrintStatus()inDerived1
//publicnewvoidPrintStatus()inDerived2
  从输入了局中,我们能够看到,固然Derived2.PrintStatus使用了new,但却仍然介入静态绑定,这是因为new只能切断Derived2.PrintStatus和Base.PrintStatus的接洽,而不克不及切断它与IFace.PrintStatus的接洽。我在Derived2的界说中从头指定完成IFace,这将使得编译器以为Derived2.PrintStatus是IFace.PrintStatus的隐式完成,因而,在静态绑准时Derived2.PrintStatus就被包含出去了。
<P>  5.谁的成绩?

  我必需指出,假如Base(Code#01)和Derived2(Code#04)同时存在的话,它们俩个中一个存在着计划上的成绩。为何如许说呢?Base的计划者在PrintStatus上使用virtual申明了他但愿派生类能透太重写这一办法来介入静态绑定,即多态性;而Derived2的计划者在PrintStatus上使用new则申明了他但愿切断Derived2.PrintStatus和Base.PrintStatus之间的接洽,这将使得Derived2.PrintStatus没法介入到Base的计划者所希冀的静态绑定中。假如在Base.PrintStatus上使用virtual(即对多态性的希冀)是公道的话,那末Derived2.PrintStatus应当换用别的一个名字了;假如在Derived2.PrintStatus上使用new(即反对介入静态绑定)是公道的,那末Base.PrintStatus应当思索是不是往失落virtual了,不然就会呈现一些奇异的举动,比方Output#01的第三行输入。

  假设承继系统中多态性举动的希冀是公道的话,那末更实践的做法应当是把Base界说成如许:

//Code#12

abstractclassBase
{
 publicabstractvoidPrintStatus();
}
  而本来Base中的完成应当下移到一个派生类中://Code#13

classDerived3:Base
{
 publicoverridevoidPrintStatus()
 {
  Console.WriteLine("publicoverridevoidPrintStatus()inDerived3");
 }
}
  如许,Derived2.PrintStatus将使得编译没法完成,从而迫使其计划者要末变动办法的名字,要末换用override润色。这类强迫使得Derived2的计划者不能不从头思索其计划的公道性。

  假设承继系统中多态性举动的希冀不老是公道呢?比方Stream有如许一个办法:

publicabstractlongSeek(longoffset,SeekOriginorigin);
  如今假定我有一个办法在处置输出流时必要用到Stream.Seek:

//Code#14

publicvoidResume(Streaminput,longoffset)
{
 //
 input.Seek(offset,SeekOrigin.Begin);
 //
}
  当我们向Resume传送一个NetworkStream的实例,Resume将会抛出一个NotSupportedException,由于NetworkStream不撑持Seek。那末这是不是申明Stream的计划有成绩呢?

  假想Resume是一个下载工具举行断点续传的办法,但是,并非一切的服务器都撑持断点续传的,因而,你必要起首判别输出流是不是撑持Seek操纵,再决意怎样处置输出流:

//Code#15

publicvoidResume(Streaminput,longoffset)
{
 if(input.CanSeek)
 {
  //
  input.Seek(offset,SeekOrigin.Begin);
  //
 }
 else
 {
  //
 }
}
  假如CanSeek为false,那就只好重新来过了。

  实践上,我们其实不能包管任何Stream的派生类都可以撑持某个(些)操纵,我们乃至不克不及包管来自统一个派生类的一切实例都撑持某个(些)操纵。你能够假想有如许一个PriorityStream,它可以依据以后登录账号的权限来决意是不是供应写操纵,这使得具有充足权限的人才网能修正数据。也许Stream的计划者已意料到这类情形的产生,以是CanRead、CanSeek和CanWrite就被到场到Stream里了。

  值得注重的是,Code#07的Derived2多是一个很糟的计划,也多是一个很有用的计划。在本文,它是一个很糟的计划,假如你充足仔细,你会发觉到Derived2的计划者但愿Derived2.PrintStatus绕过Base.PrintStatus而间接和IFace.PrintStauts举行联系关系,外表上这没甚么不当,但本色上Base.PrintStatus和IFace.PrintStauts在商定上是同质的,这意味着假如与IFace.PrintStauts举行联系关系就即是供认本人和Base.PrintStatus是同质的,如许的话,为何不间接在Derived2里重写PrintStatus呢?在《基类与接口夹杂承继的声明成绩》中,我树模了一个有用的计划,用new和接口从头完成(Interfacereimplementation)来改正非预期的多态举动。

  6.最初...

  当我的伴侣拿着成绩来找我时,我一般都不会间接给出我的谜底,而是尽我的才能向他供应充足多的可用信息,以便他可以依据他所面对的实践情形作出处置,究竟,我不会比他更懂得他的成绩,而他也应当构成他本人的关于他的成绩的思索。我但愿荡子能用本人的谜底回覆他所提出的成绩,由于只要如许,那些常识才真正属于他,而且我也信任本文已供应了充足多的可用信息。兄弟们,想来你们都看过了昨天的比赛了。我现在的痛苦状跟当时应该差不多。希望本版.net老师不吝赐教,为小弟这一批迷途的羊羔指一条阳光之道!您也知道:学习技术如果只有一个人摸索,那是一件多么痛苦的事情!还有,如果万辛能得名师或长者指点,那又是多么一件幸福和快乐的事情!

因胸联盟 发表于 2015-1-18 11:59:15

通过这次激烈的讨论,我从大家身上学到了太多,开阔了眼界,不管是支持我的还是骂我的,都感谢你们。

小魔女 发表于 2015-1-21 21:07:41

ASP.Net摆脱了以前ASP使用脚本语言来编程的缺点,理论上可以使用任何编程语言包括C++,VB,JS等等,当然,最合适的编程语言还是MS为.NetFrmaework专门推出的C(读csharp)。

再现理想 发表于 2015-1-30 22:30:38

以上是语言本身的弱点,在功能方面ASP同样存在问题,第一是功能太弱,一些底层操作只能通过组件来完成,在这点上是远远比不上PHP/JSP,其次就是缺乏完善的纠错/调试功能,这点上ASP/PHP/JSP差不多。

爱飞 发表于 2015-2-6 16:22:41

它可通过内置的组件实现更强大的功能,如使用A-DO可以轻松地访问数据库。

谁可相欹 发表于 2015-2-17 05:16:18

在asp.net虚拟主机的服务提供商中,目前首推的是CNNIC的其中一家域名注册机构---时代互联(www.now.net.cn),他们早在2001年微软刚推出Asp.net时就推出了对应的Asp.net虚拟主机了,经笔者的使用测试,他提供的Asp.net性能非常的稳定,版本也会定期的更新,目前他的

分手快乐 发表于 2015-3-5 16:43:07

微软又推出ASP.NET。这不是ASP的简单升级,而是全新一代的动态网页实现系统,用于一台WEB服务器建立强大的应用程序。是微软发展的新体系结构.NET的一部分,是ASP和.NET技术的结合。

愤怒的大鸟 发表于 2015-3-19 20:50:43

ASP在执行的时候,是由IIS调用程序引擎,解释执行嵌在HTML中的ASP代码,最终将结果和原来的HTML一同送往客户端。
页: [1]
查看完整版本: ASP.NET网页设计座谈C#编程中的多态与new关头字