[你必须知道的.NET] 第五回:深入浅出关键字---把new说透
系列文章导航:
[你必须知道的.NET] 第四回:后来居上:class和struct
[你必须知道的.NET] 第五回:深入浅出关键字---把new说透
[你必须知道的.NET] 第六回:深入浅出关键字---base和this
[你必须知道的.NET] 第七回:品味类型---从通用类型系统开始
[你必须知道的.NET] 第八回:品味类型---值类型与引用类型(上)-内存有理
[你必须知道的.NET] 第九回:品味类型---值类型与引用类型(中)-规则无边
[你必须知道的.NET] 第十回:品味类型---值类型与引用类型(下)-应用征途
[你必须知道的.NET] 第十一回:参数之惑---传递的艺术(上)
[你必须知道的.NET] 第十二回:参数之惑---传递的艺术(下)
[你必须知道的.NET] 第十三回:从Hello, world开始认识IL
[你必须知道的.NET] 第十四回:认识IL代码---从开始到现在
[你必须知道的.NET] 第十六回:深入浅出关键字---using全接触
[你必须知道的.NET]第二十二回:字符串驻留(上)---带着问题思考
[你必须知道的.NET]第三十二回,深入.NET 4.0之,Tuple一二
3. 深入浅出
作为修饰符和约束的情况,不是很难理解的话题,正如我们看到本文开篇提出的问题,也大多集中在new作为运算符的情况,因此我们研究的重点就是揭开new作为运算符的前世今生。
Jeffrey
Richter在其著作中,极力推荐读者使用ILDASM工具查看IL语言细节,从而提高对.NET的深入探究,在我认为这真是一条不错的建议,也给了自己很多提高的空间挖掘。因此,以下是本人的一点建议,我将在后续的系列中,关于学习方法论的讨论中深入探讨,这里只是顺便小议,希望有益于大家。
1
不断的学习代码;
2 经常看看IL语言的运行细节,对于提供.NET的认识非常有效。
文归正题,new运算符用于返回一个引用,指向系统分配的托管堆的内存地址。因此,在此我们以Reflector工具,来了解以下new操作符执行的背后,隐藏着什么玄机。
首先我们实现一段最简单的代码,然后分析其元数据的实现细节,来探求new在创建对象时到做了什么?
new作为运算符
使用Reflector工具反编译产生的IL代码如下为:
IL元数据分析
从而可以得出以下结论:
• new一个class时,new完成了以下两个方面的内容:一是调用newobj命令来为实例在托管堆中分配内存;二是调用构造函数来实现对象初始化。
• new一个struct时,new运算符用于调用其带构造函数,完成实例的初始化。
• new一个int时,new运算符用于初始化其值为0。
• 另外必须清楚,值类型和引用类型在分配内存时是不同的,值类型分配于线程的堆栈(stack)上,并变量本身就保存其实值,因此也不受GC的控制,;而引用类型变量,包含了指向托管堆的引用,内存分配于托管堆(managed heap)上,内存收集由GC完成。
另外还有以下规则要多加注意:
• new运算符不可重载。
• new分配内存失败,将引发OutOfMemoryException异常。
对于基本类型来说,使用new操作符来进行初始化的好处是,某些构造函数可以完成更优越的初始化操作,而避免了不高明的选择,例如:
string str = new string('*', 100);
string str = new string(new char[] {'a', 'b', 'c'});
而不是
string str = "***************************************";
4. 结论
我能说的就这么多了,至于透了没透,作者的能量也就这么多了。希望园子的大牛们常来扔块砖头,对我也是一种莫大的促进。但是作为基本的原理和应用,我想对大部分的需求是满足了。希望这种力求深入浅出的介绍,能给你分享new关键字和其本质的来龙去脉能有所帮助。
言归正传,开篇的几个题目,不知读者是否有了各自的答案,我们不妨畅所欲言,做更深入的讨论,以便揭开其真实的面纱。
[声明]
本文的关键字new指的是C#中的关键字概念,并非一般意义上的.NET CRL范畴,之所以将这个主题加入本系列,是基于在.NET体系下开发的我们,何言能逃得过基本语言的只是要点。所以大可不必追究什么是.NET,什么是C#的话题,希望大家理清概念,有的放肆。
©2007 Anytao.com