ASP.NET编程:C#锋利体验之第六讲 办法
我有个同学,他是搞Java的,他给我说“Java不是效率低,而是速度慢。”,我不是搞Java的,我实在想不透这句话的含义,难道执行速度不就是效率低吗?难道执行速度慢还成效率高了?办法又称成员函数(MemberFunction),会合表现了类或工具的举动。办法一样分为静态办法和实例办法。静态办法只能够操纵静态域,而实例办法既能够操纵实例域,也能够操纵静态域--固然这不被保举,但在某些特别的情形下会显得很有效。办法也有如域一样的5种存取润色符--public,protected,internal,protectedinternal,private,它们的意义如前所述。办法参数
办法的参数是个值得出格注重的中央。办法的参数传送有四品种型:传值(byvalue),传址(byreference),输入参数(byoutput),数组参数(byarray)。传值参数无需分外的润色符,传址参数必要润色符ref,输入参数必要润色符out,数组参数必要润色符params。传值参数在办法挪用过程当中假如改动了参数的值,那末传进办法的参数在办法挪用完成今后其实不因而而改动,而是保存本来传进时的值。传址参数恰好相反,假如办法挪用历程改动了参数的值,那末传进办法的参数在挪用完成今后也随之改动。实践上从称号上我们能够分明地看出二者的寄义--传值参数传送的是挪用参数的一份拷贝,而传址参数传送的是挪用参数的内存地点,该参数在办法表里指向的是统一个存储地位。看上面的例子及其输入:
usingSystem;classTest{staticvoidSwap(refintx,refinty){inttemp=x;x=y;y=temp;}staticvoidSwap(intx,inty){inttemp=x;x=y;y=temp;}staticvoidMain(){inti=1,j=2;Swap(refi,refj);Console.WriteLine("i={0},j={1}",i,j);Swap(i,j);Console.WriteLine("i={0},j={1}",i,j);}}
程序经编译后实行输入:
i=2,j=1
i=2,j=1
我们能够分明地看到两个互换函数Swap()因为参数的不同--传值与传址,而失掉分歧的挪用了局。注重传址参数的办法挪用不管在声明时仍是挪用时都要加上ref润色符。
笼统地说传值不会改动参数的值在有些情形下是毛病的,我们看上面一个例子:
usingSystem;classElement{publicintNumber=10;}classTest{staticvoidChange(Elements){s.Number=100;}staticvoidMain(){Elemente=newElement();Console.WriteLine(e.Number);Change(e);Console.WriteLine(e.Number);}}
程序经编译后实行输入:
10
100
我们看到即便传值体例仍旧改动了范例为Element类的工具t。但严厉意义上讲,我们是改动了工具t的域,而非工具t自己。我们再看上面的例子:
usingSystem;classElement{publicintNumber=10;}classTest{staticvoidChange(Elements){Elementr=newElement();r.Number=100;s=r;}staticvoidMain(){Elemente=newElement();Console.WriteLine(e.Number);Change(e);Console.WriteLine(e.Number);}}
程序经编译后实行输入:
10
10
传值体例基本没有改动范例为Element类的工具t!实践上,假如我们可以了解类这一C#中的援用范例(referencetype)的特征,我们便能看出下面两个例子不同!在传值过程当中,援用范例自己不会改动(t不会改动),但援用范例内含的域却会改动(t.Number改动了)!C#言语的援用范例有:object范例(包含体系内建的class范例和用户自建的class范例--承继自object范例),string范例,interface范例,array范例,delegate范例。它们在传值挪用中都有下面两个例子展现的特征。
在传值和传址情形下,C#强迫请求参数在传进之前由用户明白初始化,不然编译器报错!但我们假如有一个其实不依附于参数初值的函数,我们只是必要函数前往时失掉它的值是该怎样办呢?常常在我们的函数前往值不至一个时我们出格必要这类技能。谜底是用out润色的输入参数。但必要记着输入参数与一般的函数前往值有必定的区分:函数前往值常常存在仓库里,在前往时弹出;而输入参数必要用户事后制订存储地位,也就是用户必要提早声明变量--固然也能够初始化。看上面的例子:
usingSystem;classTest{staticvoidResoluteName(stringfullname,outstringfirstname,outstringlastname){string[]strArray=fullname.Split(newchar[]{});firstname=strArray;lastname=strArray;}publicstaticvoidMain(){stringMyName="CornfieldLee";stringMyFirstName,MyLastName;ResoluteName(MyName,outMyFirstName,outMyLastName);Console.WriteLine("Myfirstname:{0},Mylastname:{1}",MyFirstName,MyLastName);}}
程序经编译后实行输入:
Myfirstname:Cornfield,Mylastname:Lee
在函数体内一切输入参数必需被赋值,不然编译器报错!out润色符一样应当使用在函数声明和挪用两个中央,除充任前往值这一特别的功效外,out润色符ref润色符有很类似的中央:传址。我们能够看出C#完整屏弃了传统C/C++言语付与程序员莫年夜的自在度,究竟C#是用来开辟高效的下一代收集平台,平安性--包含体系平安(体系布局的计划)和工程平安(制止程序员常常犯的毛病)是它计划时的主要思索,固然我们看到C#并没有由于平安性而损失几言语的功能,这恰是C#的出色的地方,“Sharp”的地方!
数组参数也是我们常常用到的一个中央--传送大批的数组汇合参数。我们先看上面的例子:
usingSystem;classTest{staticintSum(paramsint[]args){ints=0;foreach(intninargs){s+=n;}returns;}staticvoidMain(){int[]var=newint[]{1,2,3,4,5};Console.WriteLine("TheSum:"+Sum(var));Console.WriteLine("TheSum:"+Sum(10,20,30,40,50));}}
程序经编译后实行输入:
TheSum:15
TheSum:150
能够看出,数组参数能够是数组如:var,也能够是可以隐式转化为数组的参数如:10,20,30,40,50。这为我们的程序供应了很高的扩大性。
同名办法参数的分歧会招致办法呈现多态征象,这又叫重载(overloading)办法。必要指出的是编译器是在编译时便绑定了办法和办法挪用。只能经由过程参数的分歧来重载办法,其他的分歧(如前往值)不克不及为编译器供应无效的重载信息。
办法承继
第一等的面向工具机制为C#的办法引进了virtual,override,sealed,abstract四种润色符来供应分歧的承继需求。类的虚办法是能够在该类的承继自类中改动实在现的办法,固然这类改动仅限于办法体的改动,而非办法头(办法声明)的改动。被子类改动的虚办法必需在办法头加上override来暗示。当一个虚办法被挪用时,该类的实例--亦即工具的运转时范例(run-timetype)来决意哪一个办法体被挪用。我们看上面的例子:
usingSystem;classParent{publicvoidF(){Console.WriteLine("Parent.F");}publicvirtualvoidG(){Console.WriteLine("Parent.G");}}classChild:Parent{newpublicvoidF(){Console.WriteLine("Child.F");}publicoverridevoidG(){Console.WriteLine("Child.G");}}classTest{staticvoidMain(){Childb=newChild();Parenta=b;a.F();b.F();a.G();b.G();}}
程序经编译后实行输入:
Parent.F
Child.F
Child.G
Child.G
我们能够看到classChild中F()办法的声明接纳了重写(new)的举措来屏障classParent中的非虚办法F()的声明。而G()办法就接纳了掩盖(override)的举措来供应办法的多态机制。必要注重的是重写(new)办法和掩盖(override)办法的分歧,从实质上讲重写办法是编译时绑定,而掩盖办法是运转时绑定。值得指出的是虚办法不成所以静态办法--也就是说不成以用static和virtual同时润色一个办法,这由它的运转时范例辨析机制所决意。override必需和virtual共同利用,固然也不克不及和static同时利用。
那末我们假如在一个类的承继系统中不想再使一个虚办法被掩盖,我们该如何做呢?谜底是sealedoverride(密封掩盖),我们将sealed和override同时润色一个虚办法即可以到达这类目标:sealedoverridepublicvoidF()。注重这里必定是sealed和override同时利用,也必定是密封掩盖一个虚办法,大概一个被掩盖(而不是密封掩盖)了的虚办法。密封一个非虚办法是没成心义的,也是毛病的。看上面的例子:
//sealed.cs//csc/t:librarysealed.csusingSystem;classParent{publicvirtualvoidF(){Console.WriteLine("Parent.F");}publicvirtualvoidG(){Console.WriteLine("Parent.G");}}classChild:Parent{sealedoverridepublicvoidF(){Console.WriteLine("Child.F");}overridepublicvoidG(){Console.WriteLine("Child.G");}}classGrandson:Child{overridepublicvoidG(){Console.WriteLine("Grandson.G");}}
笼统(abstract)办法在逻辑上相似于虚办法,只是不克不及像虚办法那样被挪用,而只是一个接口的声明而非完成。笼统办法没有相似于{…}如许的办法完成,也不同意如许做。笼统办法一样不克不及是静态的。含有笼统办法的类必定是笼统类,也必定要加abstract类润色符。但笼统类其实不必定要含有笼统办法。承继含有笼统办法的笼统类的子类必需掩盖并完成(间接利用override)该办法,大概组合利用abstractoverride使之持续笼统,大概不供应任何掩盖和完成。后二者的举动是一样的。看上面的例子:
//abstract1.cs//csc/t:libraryabstract1.csusingSystem;abstractclassParent{publicabstractvoidF();publicabstractvoidG();}abstractclassChild:Parent{publicabstractoverridevoidF();}abstractclassGrandson:Child{publicoverridevoidF(){Console.WriteLine("Grandson.F");}publicoverridevoidG(){Console.WriteLine("Grandson.G");}}
笼统办法能够笼统一个承继来的虚办法,我们看上面的例子:
//abstract2.cs//csc/t:libraryabstract2.csusingSystem;classParent{publicvirtualvoidMethod(){Console.WriteLine("Parent.Method");}}abstractclassChild:Parent{publicabstractoverridevoidMethod();}abstractclassGrandson:Child{publicoverridevoidMethod(){Console.WriteLine("Grandson.Method");}}
归根结柢,我们捉住了运转时绑定和编译时绑定的基础机理,我们便能看破办法出现出的各种overload,virtual,override,sealed,abstract等形状,我们才干使用好办法这一利器!
内部办法
C#引进了extern润色符来暗示内部办法。内部办法是用C#之外的言语完成的办法如Win32API函数。如前所是内部办法不克不及是笼统办法。我们看上面的一个例子:
usingSystem;usingSystem.Runtime.InteropServices;classMyClass{staticexternintMessageBoxA(inthWnd,stringmsg,stringcaption,inttype);publicstaticvoidMain(){MessageBoxA(0,"Hello,World!","ThisiscalledfromaC#app!",0);}}
程序经编译后实行输入:
这里我们挪用了Win32API函数intMessageBoxA(inthWnd,stringmsg,stringcaption,inttype)。
我觉得这个学习方法很重要。初学者应该跟我一样有同样一个毛病。那就是急于求成。很想就自己做出个小小的系统来。可真要动手,却又茫然而不知所措。为什么会这样呢?因为我们没有耐心去学习基础知识。写根本看不到什么效果的测试代码。 弱类型造成潜在的出错可能:尽管弱数据类型的编程语言使用起来回方便一些,但相对于它所造成的出错几率是远远得不偿失的。 Asp.net脚本的出现,为ASP空间带来了更高的稳定性,同时也为程序员建站提供更高环境! 关于ASP.NET功能上,ASP.NET比微软以前的ASP(96年出现)有更强大的library,更好的稳定性。ASP.NET可以使用.NETFramework中所有组件(也就是说.NET能实现的,ASP.NET一样能实现)。 ASP.NET:ASP.net是Microsoft.net的一部分,作为战略产品,不仅仅是ActiveServerPage(ASP)的下一个版本;它还提供了一个统一的Web开发模型,其中包括开发人员生成企业级Web应用程序所需的各种服务。ASP.NET的语法在很大程度上与ASP兼容,同时它还提供一种新的编程模型和结构,可生成伸缩性和稳定性更好的应用程序,并提供更好的安全保护。 市场决定一切,我个人从经历上觉得两者至少在很长时间内还是要共存下去,包括C和C++,至少从找工作就看得出来,总不可能大家都像所谓的时尚一样,追捧一门语言并应用它。 有一丝可惜的是,这个系列太强了,Java阵营的朋友根本就是哑口无言...争论之火瞬间被浇灭,这不是我想这么早就看到的,但是值了。 是目前ASP在UNIX/Linux上的应用可以说几乎为0)。所以平台的局限性和ASP自身的安全性限制了ASP的广泛应用。
页:
[1]