|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
net网页编程的设计机制:首先产生一个中间码,第二部编译为本地(机器)码。这个机制有很大的缺点。目次
- 简介
- 静态查找
- 范例
- 静态操纵
- 运转时查找
- 示例
- 带有静态参数的重载剖析
- 静态言语运转时
- 已知成绩
- 定名参数和可选参数
- 互操纵特征
- 静态引进
- 无PIA的编译
- ref省略ref
- 已知成绩
- 变性
- COMExampleCOM示例
- RelationshipwithVisualBasic与VisualBasic的干系
- 资本
简介
MicrosoftVisualC#3.0作为VisualStudio2008的一部分公布以来已快一年了。在VSManagedLanguages团队,我们一向勉力创立该言语的下一个版本(没甚么欣喜,就是C#4.0),而这个文档是我们如今所看到的、企图中的言语特征的第一个公然形貌。
请记着本文内容都是针对产物初期的,并且未来会改动。这么早地共享我们的企图,一部分缘故原由是为了猎取某些反应,这些反应会让我们在产物终极公布出来之前改善它。
与该白皮书一同公布的另有VisualStudio2010的第一个公然的CTP(社区手艺预览),它经由过程VirtualPC映像公布,任何人都能够试用。请利用这个CTP来把玩和实验这些特征,并让我们晓得您的设法。我们但愿晓得您对这个初期产物的了解和不满,特别是新增加的完成特征是不是不具有终极产物应有的质量和不乱性。这个CTP的目标不是为您供应一个高临盆力的事情情况,而是让您对我们正在为下一个公布版做些甚么有个印象。
该CTP包括了大批的练习训练,个中一些侧重于C#4.0的言语新特征。要具体懂得这些特征的经常使用场景,这些练习训练是尽好的上手教程。您能够以为该白皮书是这些练习训练的陪伴文档,周全地先容了言语的特征和事情道理,而那些练习训练则是先容详细的场景。
C#4.0
C#4.0的次要主题是静态编程。对象的意义变得愈来愈“静态”,它们的布局和举动没法经由过程静态范例来捕捉,大概最少编译器在编译程序时没法得知对象的布局和举动。比方——
a.来主动态编程言语——如Python或Ruby——的对象
b.经由过程IDispatch会见的COM对象
c.经由过程反射会见的一样平常.NET范例
d.布局产生过变更的对象——如HTMLDOM对象
只管C#仍然是静态范例言语,但我们的目标是改良它与这些对象的交互。
另外一个主要主题是与VisualBasic协同前进(co-evolution)。未来我们但愿仅保护每种言语独自的特性,而主要的新特征会同时引进两种言语。它们的区分仅仅是作风和感到上的,而不在于特征集方面。
C#4.0中的新特征分为四组——
静态查找
静态查找同意在编写办法、运算符和索引器挪用、属性和字段会见乃至对象挪用时,绕过C#静态范例反省,而在运转时举行剖析。
定名参数和可选参数
如今C#中的参数能够经由过程在成员声明中为其供应默许值来指名它是可选的。在挪用该成员时,可选参数能够疏忽。别的,在传进任何参数时都能够依照参数名而不是地位举行传送。
特定于COM的互操纵特征
静态查找和定名参数和可选参数都有助于使针对COM的编程不再像明天如许疾苦。在这些特征之上,我们还增加了大批其他小特征,进一步改良了互操纵体验。
变性
已往,IEnumerable<string>并非IEnumerable<object>。如今它是了——C#包括了范例平安的“协变性和逆变性(co-andcontravariance)”并且通用的BCL也将使用这一特征举行更新。
静态查找
静态查找能够用一致的体例来静态挪用成员。有了静态查找,当你拿到一个对象时,不必管它是来自于COM仍是IronPython、HTMLDOM或是反射;只必要对其举行操纵便可,运转时会帮你指出针对特定的对象,这些操纵的详细意义。
这给你带来了伟大的天真性,并能极年夜水平地精简代码,但它陪伴着一个伟大的弱点——不会为这些操纵保护静态范例。在编译时,会假定静态对象撑持任何操纵,而假如它不撑持某个操纵,则只要到运转时才干失掉毛病。有的时分这不会有任何丧失,由于对象基本不具有静态范例,并且他情形下必需在简便和平安之间举行衡量。为了匡助举行衡量,C#的一个计划方针就是同意在每一个独自的挪用当选择是不是利用静态举动。
范例
C#4.0引进了一个新的静态范例,称为dynamic。当你具有了一个dynamic范例的对象后,你“对他做的事变”只会在运转时举行剖析——
dynamicd=GetDynamicObject(...);
d.M(7);
C#编译器同意你利用任何参数在d上挪用一个办法,由于它的范例是dynamic。运转时会反省d的实践范例,并检测在它下面“用一个int挪用M”是甚么意义。
能够以为dynamic范例是object范例的一个特别版本,指出了对象能够静态地利用。选择是不是利用静态举动很复杂——任何对象都能够隐式转换为dynamic,“挂起信托”直到运转时。反之,从dynamic就任何其他范例都存在“赋值转换”,能够相似于赋值的布局中举行隐式转换——
1.dynamicd=7;//implicitconversion
2.inti=d;//assignmentconversion静态操纵
不但是办法挪用,字段和属性会见、索引器和运算符挪用乃至托付挪用都能够静态地分拨——
dynamicd=GetDynamicObject(…);
- d.M(7);//callingmethods
- d.f=d.P;//gettingandsettingsfieldsandproperties
- d[“one”]=d[“two”];//gettingandsettingthorughindexers
- inti=d+3;//callingoperators
- strings=d(5,7);//invokingasadelegate
C#编译器在这里的脚色就是打包有关“在d上做甚么”的需要信息,使得运转时能够猎取这些信息并检测关于实践对象d这些操纵切实其实切寄义。能够以为这是将编译器的部合作作提早到了运转时。
任何静态操纵的了局自己也是dynamic范例的。
运转时查找
在运转时,静态操纵将依据方针对象d的实质举行分拨——
COM对象
假如d是一个COM对象,则操纵经由过程COMIDispatch举行静态分拨。这同意挪用没有主互操纵程序集(PrimaryInteropAssembly,PIA)的COM范例,并依附C#中没有对应观点的COM特征,如索引属性和默许属性。
静态对象
假如d完成了IDynamicObject接口,则哀求d本身来实行该操纵。因而经由过程完成IDynamicObject接口,范例能够完整从头界说静态操纵的意义。这在静态言语——如IronPython和IronRuby——中大批利用,用于完成他们的静态对象模子。API也会利用这类对象,比方HTMLDOM同意间接利用属性语法来会见对象的属性。
复杂对象
除此以外,则d是一个尺度的.NET对象,操纵是经由过程在其范例长进行反射来分拨的,C#的“运转时绑定器(runtimebinder)”完成了运转时的C#查找和重载剖析。其面前的实质是将C#编译器作为运转时组件运转,来“完成”被静态编译器提早的静态操纵。
示例
思索上面的代码——
dynamicd1=newFoo();
dynamicd2=newBar();
strings;
d1.M(s,d2,3,null);
因为对M举行挪用的承受者是dynamic范例的,C#编译器不会试图剖析该挪用的意义。而是将有关该挪用的信息存储起来,供运转时利用。该信息(一般称作“无效载荷”)实质上等价于——“利用上面的参数实行一个称作M的实例办法——
- 1.一个string
- 2.一个dynamic
- 3.一个int字面值3
- 4.一个object字面值null”
在运转时,假定d1的实践范例Foo不是COM范例,也没有完成IDynamicObject。在这类情形下,C#运转时绑定器担当起了重载剖析的事情,这是基于运转时范例信息完成的,依照上面的步骤举行处置——
- 1.利用反射猎取两个对象d1和d2的实践运转时范例,它们没有静态范例(包含静态范例dynamic)。了局为d1是Foo范例而d2是Bar。
- 2.利用一般的C#语义在Foo范例上对M(string,Bar,3,null)挪用举行办法查找和重载剖析。
- 3.假如找到了该办法,则挪用它;不然抛出运转时非常。
带有静态参数的重载剖析
即使办法挪用的承受者是静态范例的,重载剖析仍然产生在运转时。当一个或多个实参是dynamic范例时就会呈现这类情形——
Foofoo=newFoo();
dynamicd=newBar();
varresult=foo.M(d);
C#运转时绑定器会基于d的运转时范例——也就是Bar——在Foo上M办法的静态可知(staticallyknown)重载之间举行选择。其了局是dynamc范例。
静态言语运转时
静态言语运转时(DynamicLanguageRuntime,DLR)是静态查找的底层完成的一个主要组件,也是.NET4.0中新增的API。
DLR不但为C#静态查找,还为良多其他.NET上的静态言语——如IronPython和IronRuby——的完成供应了底层的基本举措措施。这一通用基本举措措施确保了高度的互操纵性,更主要的是,DLR供应了出色的缓存机制,使得运转时分拨的效力失掉伟大的改良。
关于利用C#静态查找的用户来讲,除更高的功能以外,基本感到不到DLR的存在。不外,假如你但愿完成本人的静态分拨对象,可使用IDynamicObject接口来与DLR互操纵,并向个中拔出本人的举动。这是一个十分初级的义务,请求对DLR的外部事情道理有相称深切的懂得。关于编写API的人,值得在这些成绩上花些工夫,如许可以更普遍地改良可用性,比方为一个自己就是静态的范畴编写类库。
已知成绩
这里大概有一些限定或与你希冀的了局分歧。
- DLR同意从一个暗示类的对象创立对象。但是,C#确当前完成还不具有撑持这一功效的语法。
- 静态查找不克不及查找扩大办法。不管扩大办法是不是依附该挪用的静态高低文(也就是呈现了using语句),由于该高低文信息其实不会作为无效载荷的一部分保存上去。
- 匿名函数(也就是lambda表达式)不克不及作为实参传送给静态办法挪用。在不晓得要转换成甚么范例的情形下,编译器不克不及绑定(也就是“了解”)一个匿名函数。
这些限定招致的了局就是很难在静态对象上利用LINQ查询——
varresult=collection.Select(e=>e+5);
dynamiccollection=...;
假如Selected办法是个扩大办法,静态查找将找不到它。即使它是一个实例办法,下面的代码也没法编译,由于lambda表达式不克不及作为参数传送给静态操纵。
在C#4.0中没有企图办理这些限定。
定名参数和可选参数
定名参数和可选参数是两个一模一样的功效,但一般一同利用。在举行成员挪用时,能够疏忽可选参数;而定名参数的体例能够经由过程称号来供应一个参数,而无需依附它在参数列表中呈现的地位。
有些API——特别是COM接口——如Office主动化API——的确自己就是经由过程定名参数和可选参数编写的。之前在C#中挪用这些API十分疾苦,特别有的时分必要多达30几个参数都必需显式传送,而个中年夜多半都具有公道的默许值,是能够疏忽的。
即使是编写.NET中的API,你也会发明良多时分你在自愿为分歧的参数组合体例编写一个办法的大批重载情势,以便给挪用者供应最高的可用性。在这类情形下,可选参数就会成为一种十分有效的替换体例。
可选参数
为一个参数供应默许值就能够将其声明为可选的——
publicvoidM(intx,inty=5,intz=7);
这里的y和z就是可选参数,在挪用时能够疏忽——
M(1,2,3);//ordinarycallofM
M(1,2);//omittingz–equivalenttoM(1,2,7)
M(1);//omittingbothyandz–equivalenttoM(1,5,7)
定名的和可选的实参
C#4.0不同意疏忽逗号之间的实参,好比M(1,,3)。不然会招致大批不成读的、必要“数逗号”的代码。替换体例是任何参数都能够经由过程名字传送。因而假如在挪用M时只但愿疏忽y,能够写——
- M(1,z:3);//passingzbyname
或
- M(x:1,z:3);//passingbothxandzbyname
乃至
- M(z:3,x:1);//reversingtheorderofarguments
这几种情势都是等价的,不外参数老是依照其呈现的按次举行求值,因而关于最初一个示例来讲,3会在1之前求值。
可选参数和定名参数不但能够用在办法挪用中,还能够用在索引器和机关器中。
省略ref
因为接纳了分歧的编程模子,良多COMAPI包括大批的援用参数。与C#中的ref相反,这些参数其实不意味着要修正传进的实参以供挪用方以后利用,而只是别的一种传送参数值的复杂体例。
C#程序员必需为一切这些ref参数创立一时变量,并按援用举行传送,这看上往一点也分歧理。因而,关于COM办法,C#编译器同意按值传送这些参数,并主动天生寄存传进值的一时变量,并在挪用前往后抛弃这些变量。利用这类体例,挪用方看到的语义是按值传送,并且不会有任何反作用,而被挪用的办法失掉的仍然是一个援用。
已知成绩
一小部分COM接口特征没有呈现在C#中。特别是索引属性和默许属性。假如是静态会见COM,能够用之条件到的特征来办理,但静态范例的C#代码仍旧没法辨认它们。
在C#4.0中没有企图办理这些残剩的速率丧失。
变性
泛型的某个方面会让人感应奇异,好比上面的代码是分歧法的——
IList<string>strings=newList<string>();
IList<object>objects=strings;第二个赋值是不同意的,由于strings和objects的元素范例其实不一样。如许做有这充实的缘故原由。假如同意那样写的话,你大概会写——
objects[0]=5;
strings=strings[0];这会同意将int拔出strings列表中,然后将其作为string掏出。这会损坏范例平安。
但是,关于某些接口来讲上述情形其实不会产生,特别是不克不及将对象拔出汇合时。比方IEnumerable<T>就是如许的接口。假如改成——
IEnumerable<object>objects=strings;
如许就没法经由过程objects将毛病范例的工具拔出到strings中了,由于objects没有拔出元素的办法。变性(variance)就是用于在这类能包管平安的情形下举行赋值的。了局就是良多之前让我们感应奇异的情形如今能够事情了。
协变性
在.NET4.0中,IEnumerable<T>接口将会依照上面的体例举行界说——
publicinterfaceIEnumerable<outT>:IEnumerable
{
IEnumerator<T>GetEnumerator();
}
publicinterfaceIEnumerator<outT>:IEnumerator
{
boolMoveNext();
TCurrent{get;}
}
这些声明中的“out”指出T只能呈现在接口的输入地位——假如不是如许的话,编译器会报错。有了这一限定,接口关于T范例就是“协变的”,这意味着假如A能够按援用转换为B,则IEnumerable<A>能够看成IEnumerable<B>利用。其了局是,任何一个字符串序列也就是一个对象序列了。
这很有效,比方在LINQ办法中。利用下面的界说——
varresult=strings.Union(objects);//succeedswithanIEnumerable<object>
之前如许做是不同意的,你必需做一些贫苦的包装,使得两个序列具有不异的元素范例。
逆变性
范例参数还能够具有“in”润色符,限定它们只能呈现在输出地位上。比方IComparer<T>—
publicinterfaceIComparer<inT>
{
publicintCompare(Tleft,Tright);
}
其了局有点让人利诱,就是IComparer<object>能够作为IComparer<string>利用!如许思索这个了局就会很成心义——假如一个对照器能够对照恣意两个object,它固然也能够对照两个string。这类性子被称作“逆变性(contravariance)”。
泛型范例能够同时具有带有in和out润色符的范例参数,比方Func<...>托付范例——
publicdelegateTResultFunc<inTArg,outTResult>(TArgarg);
很分明参数永久都是传进的,而了局永久只能是传出的。因而,Func<object,string>能够用作Func<string,object>。
限定
变性范例参数只能在接口和托付范例中声明,这是CLR的限定。变性只能使用在范例参数的按援用转换之间。比方,IEnumerable<int>不克不及作为IEnumerable<object>利用,由于从int到object的转换是装箱转换,而不是援用转换。
还要注重的是,CTP中并没有包括后面提到的.NET范例的新版本。为了实验变性,你必要本人声明变性接口和托付范例。
COM示例
这里有一个稍年夜一些的Office主动化示例,展现了年夜部分C#新特征的实践使用。
usingSystem;
usingSystem.Diagnostics;
usingSystem.Linq;
usingExcel=Microsoft.Office.Interop.Excel;
usingWord=Microsoft.Office.Interop.Word;
classProgram
{
staticvoidMain(string[]args){
varexcel=newExcel.Application();
excel.Visible=true;
excel.Workbooks.Add();//optionalargumentsomitted
excel.Cells[1,1].Value="ProcessName";//nocasts;Valuedynamically
excel.Cells[1,2].Value="MemoryUsage";//accessed
varprocesses=Process.GetProcesses()
.OrderByDescending(p=>p.WorkingSet)
.Take(10);
inti=2;
foreach(varpinprocesses){
excel.Cells[i,1].Value=p.ProcessName;//nocasts
excel.Cells[i,2].Value=p.WorkingSet;//nocasts
i++;
}
Excel.Rangerange=excel.Cells[1,1];//nocasts
Excel.Chartchart=excel.ActiveWorkbook.Charts.
Add(After:excel.ActiveSheet);//namedandoptionalarguments
chart.ChartWizard(
Source:range.CurrentRegion,
Title:"MemoryUsagein"+Environment.MachineName);//named+optional
chart.ChartStyle=45;
chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
Excel.XlCopyPictureFormat.xlBitmap,
Excel.XlPictureAppearance.xlScreen);
varword=newWord.Application();
word.Visible=true;
word.Documents.Add();//optionalarguments
word.Selection.Paste();
}
}比起C#3.0编写的等价代码,这段代码加倍简便可读。
特别注重怎样静态地会见Value属性的。这实践上是一个索引属性,也就是说,这是一个带有参数的属性;C#其实不能了解这类属性。但是其参数是可选的。因为会见是静态举行的,运转时COM绑定器会晓得用默许值交换参数并挪用索引属性。因而,静态COM能够制止会见Excel地区的使人利诱的Value2属性。
与VisualBasic的干系
C#4.0中引进的大批特征已大概将要以别的的情势引进VisualBasic中——
- VB中的迟绑定在良多方面都和C#中的静态查找很像,而且未来会更多地利用DLR,与C#加倍等价。
- 定名参数和可选参数在VisualBasic中已存在好久了,这个特征的C#版本分明会使与VB的互操纵才能最年夜化。
- 无PIA和变性会同时引进VB和C#。
VB也增添了大批已经是C#所独占的特征。C#和VB将来的版本在功效大将加倍等价,这关于每一个人都是无益的
资本
有关C#4.0的一切可用的资本都能够在C#DevCenter找到(www.csharp.net)。该白皮书和其他资本能够在CodeGallery站点找到(code.msdn.com/csharpfuture)。祝兴奋。
原文地点:http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=csharpfuture&DownloadId=3550(Word格局,需承受允许协定并下载。)
在VC.net的版本上,为了让C++运行在.NETFramework中,微软为C++引进了托管,就是托管C++(ManagedC++),这个根本就没有流行起来,自托管C++产生以后就没有收到过好评。 |
|