|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
一般的指的.net就是跟net网页编程相对的那种,主要是做企业级应用的。你如果想学这个,主要就是学C#和数据库。(ASP.NET好像很重要的,应该也要学的,ASP.NET上好像可以结合VB和C#等多种语言,但是微软主推C#)系列文章目次索引:《你必需晓得的.NET》
<br>说在,开篇之前明天Artech兄在《关于TypeInitializer和BeforeFieldInit的成绩,看看人人可否给出准确的注释》一文中让我们熟悉了一个关于范例机关器挪用实行的风趣示例,个中也响应提出了一些关于beforefieldinit关于范例机关器挪用机会的切磋,关于我们很好的了解范例机关器给出了一个很好的使用理论体验。
熟悉范例机关器,熟悉beforefieldinit,更深切存眷CLR实行机理,咀嚼细节之美。1弁言明天Artech兄在《关于TypeInitializer和BeforeFieldInit的成绩,看看人人可否给出准确的注释》一文中让我们熟悉了一个关于范例机关器挪用实行的风趣示例,个中也响应提出了一些关于beforefieldinit关于范例机关器挪用机会的切磋,关于我们很好的了解范例机关器给出了一个很好的使用理论体验。
作为增补,本文但愿从基本入手下手再层层深切,把《关于TypeInitializer和BeforeFieldInit的成绩,看看人人可否给出准确的注释》一文中没有注释的观点和道理,举行需要的增补,比方更周全的熟悉范例机关器,熟悉BeforeFieldInit。并在此基本上,切磋一点关于范例机关器的理论使用,同时代看可以回覆个中示例运转的了局。
空话少说,我们入手下手。
2熟悉对象机关器和范例机关器
在.NET中,一个类的初始化历程是在机关器中举行的。而且依据机关成员的范例,分为范例机关器(.cctor)和对象机关器(.ctor),个中.cctor和.ctor为两者在IL代码中的指令暗示。.cctor不克不及被间接挪用,其挪用划定规矩恰是本文欲加论述的重点,详见后文的剖析;而.ctor会在范例实例化时被主动挪用。
基于对范例机关器的切磋,我们有需要起首完成一个复杂的类界说,个中包含一般的机关器和静态机关器,比方- //Release:code01,2008/11/02
复制代码- //Author:Anytao,http://www.anytao.com
复制代码- message="Initializeinstaticconstructor.";
复制代码- [/code][code]publicUser()
复制代码- //Author:Anytao,http://www.anytao.com0
复制代码- //Author:Anytao,http://www.anytao.com1
复制代码- //Author:Anytao,http://www.anytao.com2
复制代码- //Author:Anytao,http://www.anytao.com3
复制代码- //Author:Anytao,http://www.anytao.com4
复制代码- //Author:Anytao,http://www.anytao.com6
复制代码- //Author:Anytao,http://www.anytao.com7
复制代码- //Author:Anytao,http://www.anytao.com2
复制代码- //Author:Anytao,http://www.anytao.com3
复制代码- //Author:Anytao,http://www.anytao.com3
复制代码- //Author:Anytao,http://www.anytao.com3
复制代码 我们将上述代码利用ILDasm.exe工具反编译为IL代码,能够很便利的找到响应的范例机关器和对象机关器的影子,如图
<br>
然后,我们复杂的来懂得一下对象机关器和范例机关器的观点。
在天生的IL代码中将能够看到对应的ctor,范例实例化时会实行对应的机关器举行范例初始化的操纵。
关于实例化的历程,计划到对照庞大的实行按次,依照范例基本条理举行初始化的历程能够参阅《你必需晓得的.NET》7.8节“动态之间:静态和非静态”一文中有具体的先容和剖析,本文中将不做过量切磋。
本文的重点以考查范例机关器为主,以是在此不举行过量切磋。
用于实行对静态成员的初始化,在.NET中,范例在两种情形下会产生对.cctor的挪用:
- 为静态成员指定初始值,比方上例中只要静态成员初始化,而没有静态机关函数时,.cctor的IL代码完成为:
- 完成显式的静态机关函数,比方上例中有静态机关函数存在时,将起首实行静态成员的初始化历程,再实行静态机关函数初始化历程,.cctor的IL代码完成为:
同时,我们必需明白一些静态机关函数的基础划定规矩,包含:
- 必需为静态无参机关函数,而且一个类只能有一个。
- 只能对静态成员举行初始化。
- 静态无参机关函数能够和非静态无参机关函数共存,区分在于两者的实行工夫,详见《你必需晓得的.NET》7.8节“动态之间:静态和非静态”的叙述,其他更多的区分和差别也详见本节的形貌。
3深切实行历程
由于范例机关器自己的特性,在必定水平上决意了.cctor的挪用机会并不是是一个断定的观点。由于范例机关器都是private的,用户不克不及显式挪用范例机关器。以是关于范例机关器的实行机会成绩在.NET中次要包含两种计划:
- precise体例
- beforefieldinit体例
两者的实行不同次要表现在是不是为范例完成了显式的静态机关函数,假如完成了显式的静态机关函数,则依照precise体例实行;假如没有完成显式的静态机关函数,则依照beforefieldinit体例实行。
为了说分明范例机关器的实行情形,我们起首在观点上必需明白一个条件,那就是precise的语义明白了.cctor的挪用和挪用存取静态成员的机会存在准确的干系,以是换句话说,范例机关器的实行机会在语义上决意因而否显式的声了然静态机关函数,和存取静态成员的机会,这两个要素。
我们仍是从User类的完成提及,逐一过招剖析这两种体例的实行历程。
3.1precise体例
起首完成显式的静态机关函数计划,为:- //Author:Anytao,http://www.anytao.com
复制代码- //Author:Anytao,http://www.anytao.com0
复制代码- //Author:Anytao,http://www.anytao.com2
复制代码- //Author:Anytao,http://www.anytao.com3
复制代码 对应的IL代码为:- message="Initializeinstaticconstructor.";0
复制代码- message="Initializeinstaticconstructor.";2
复制代码- //Author:Anytao,http://www.anytao.com0
复制代码- message="Initializeinstaticconstructor.";4
复制代码- message="Initializeinstaticconstructor.";5
复制代码- message="Initializeinstaticconstructor.";6
复制代码- message="Initializeinstaticconstructor.";7
复制代码- message="Initializeinstaticconstructor.";8
复制代码- message="Initializeinstaticconstructor.";9
复制代码- //Author:Anytao,http://www.anytao.com0
复制代码- message="Initializeinstaticconstructor.";4
复制代码 为了举行对照剖析,我们必要起首剖析beforefieldinit体例的实行情形,以是接着持续。。。
3.2beforefieldinit体例
为User范例,不完成显式的静态机关函数计划,为:- //Author:Anytao,http://www.anytao.com
复制代码- //Author:Anytao,http://www.anytao.com2
复制代码 对应的IL代码为:- message="Initializeinstaticconstructor.";0
复制代码- message="Initializeinstaticconstructor.";2
复制代码- //Author:Anytao,http://www.anytao.com0
复制代码- message="Initializeinstaticconstructor.";4
复制代码- message="Initializeinstaticconstructor.";5
复制代码- message="Initializeinstaticconstructor.";6
复制代码- //Author:Anytao,http://www.anytao.com0
复制代码- message="Initializeinstaticconstructor.";4
复制代码 3.3剖析不同
从IL代码的实行历程而言,我们起首能够懂得的是在显式和隐式完成范例机关函数的外部,除增加新的初始化操纵以外,两者的完成是基础不异的。以是要找出两种体例的不同,我们终极将着眼点锁定在两者元数据的声明上,隐式体例多了一个称为beforefieldinit标志的指令。
那末,beforefieldinit事实暗示甚么样的语义呢?ScottAllen对此举行了具体的注释:beforefieldinit为CLR供应了在任什么时候候实行.cctor的受权,只需该办法在第一次会见范例的静态字段之前实行便可。
以是,假如对precise体例和beforefieldinit体例举行对照时,两者的不同就在因而否在元数据声明时标志了beforefieldinit指令。precise体例下,CLR必需在第一次会见该范例的静态成员大概实例成员之前实行范例机关器,也就是说必需恰好在存取静态成员大概创立实例成员之前完成范例机关器的挪用;beforefieldinit体例下,CLR能够在任什么时候候实行范例机关器,必定水平上完成了对实行功能的优化,因而较precise体例加倍高效。
值得注重的是,当有多个beforefieldinit机关器存在时,CLR没法包管这多个机关器之间的实行按次,因而我们在实践的编码时应当只管制止这类情形的产生。
4回回成绩,需要的小结
本文源于Artech兄的一个成绩,但愿经由过程上文的剖析能够给出一点值得参考的背景。如今就关于TypeInitializer和BeforeFieldInit的成绩,看看人人可否给出准确的注释一文中的几个示例举行一些持续的剖析:
- 在蒋兄的入手下手的示例完成中,能够很简单的来断定关于显式完成了静态机关函数的情形,范例机关器的挪用在恰好援用静态成员之前产生,以是不论是否在Main中声明
- //Author:Anytao,http://www.anytao.com12
复制代码 实行的了局不受影响。
- 而在没有显式完成静态机关函数的情形下,beforefieldinit优化了范例机关器的实行不在断定的工夫实行,只需其实静态成员援用大概范例实例产生之前便可,以是在Debug情况下挪用的机会变得不按常理。但是在Release优化形式下,beforefieldinit的实行按次其实不受
- //Author:Anytao,http://www.anytao.com12
复制代码 的影响,完整切合beforefieldinit优化实行的语义界说。
- 关于最初一个静态成员承继情形的了局,正像本文入手下手形貌的逻辑一样,范例机关器是在静态成员被挪用大概创立实例时产生,以是示例的了局是完整恪守标准的。不外,我其实不倡议子类最好不要挪用父类静态成员,缘故原由是作为承继机制而言,子承父业是承继的基础标准,除强迫为private以外,一切的成员大概办法都应在子类中可见。而关于存在的潜伏成绩,更好的以标准来束缚大概会更好。个中,静态办法必定水平上是一种布局化的完成机制,在面向对象的承继干系中,实质上就存在必定的不敷。
- 在c#标准中,关于beforefieldinit的把持已引发良多的存眷和非议,一方面beforefieldinit体例能够无效的优化挪用功能,可是以显式和大概隐式完成静态机关函数的体例不克不及更有直不雅的让程序开辟者来把持,因而在今后版本的c#中,能完成基于特征的声明体例来把持,是值得等候的。
- 另外一方面,在有两个范例的范例机关器互相援用的情形下,CLR没法包管范例机关器的挪用按次,对程序开辟者而言,我一样夸大了关于范例机关器而言,我们应当只管制止请求按次相干的营业逻辑,由于良多时分实行的按次并不是声明的按次,这是值得存眷的。
5结论
除增补Artech老兄的成绩,本文算是持续了关于范例机关器在《你必需晓得的.NET》7.8节“动态之间:静态和非静态”中的切磋,以更周全的视角来进一步阐释这个成绩。在最初,关于beforefieldinit标志引发的范例机关器挪用优化的成绩,固然没有完整100%的懂得在Debug形式下的CLR挪用举动,可是深切细节我们能够掌控关于言语以内更多的了解,从这点而言,本文是个入手下手。
参考文献
《你必需晓得的.NET》7.8节“动态之间:静态和非静态”
Artech:关于TypeInitializer和BeforeFieldInit的成绩,看看人人可否给出准确的注释
经由过程七个关头编程技能得益于静态内容来自:http://www.ckuyun.com/anytao/archive/2008/11/02/must_net_23.html
学习asp.net两个月有余了,除了对html、web控件比较熟悉(应该是说都能理解和接受)之外,竟不知道自己还会什么。看了两本书:《精通asp.net网络编程》(人民邮电出版社)、《asp.net实用案例教程》(清华大学出版社)。 |
|