您的位置:首页 > 其它

[你必须知道的.NET] 第五回:深入浅出关键字---把new说透(转载)

2007-05-26 09:17 253 查看

[你必须知道的.NET] 第五回:深入浅出关键字---把new说透

作者:Anytao

本文将介绍以下内容:

面向对象基本概念
new关键字深入浅出
对象创建的内存管理

1. 引言

园子里好像没有或者很少把new关键字拿出来说的,那我就占个先机吧,呵呵。那么,我们到底有必要将一个关键字拿出来长篇大论吗?看来是个问题。回答的关键是:你真的理解了new吗?如果是,那请不要浪费时间,如果不是,那请继续本文的循序之旅。

下面几个 问题可以大概的考察你对new的掌握,开篇之前,希望大家做个检验,如果通过了,直接关掉本页即可。如果没有通过,希望本文的阐述能帮你找出答案。

new一个class对象和new一个struct或者enum有什么不同?
new在.NET中有几个用途,除了创建对象实例,还能做什么?
new运算符,可以重载吗?
范型中,new有什么作用?
new一个继承下来的方法和override一个继承方法有何区别?
int i和int i = new int()有什么不同?

2. 基本概念

一般说来,new关键字在.NET中用于以下几个场合,这是MSDN的典型解释:

作为运算符, 用于创建对象和调用构造函数。

本文的重点内容,本文在下一节来重点考虑。

作为修饰符,用于向基类成员隐藏继承成员。

作为修饰符,基本的规则可以总结为:实现派生类中隐藏方法,则基类方法必须定义为virtual;new作为修饰符,实现隐藏基类成员时,不可和override共存,原因是这两者语义相斥:new用于实现创建一个新成员,同时隐藏基类的同名成员;而override用于实现对基类成员的扩展。

另外,如果在子类中隐藏了基类的数据成员,那么对基类原数据成员的访问,可以通过base修饰符来完成。

例如:

IL元数据分析
.method public hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 2
.locals init (
[0] int32 num,
[1] int32 num2,
[2] class Anytao.net.My_Must_net._05_new.MyClass class2,
[3] valuetype Anytao.net.My_Must_net._05_new.MyStruct struct2)
L_0000: nop

//初始化j为0
L_0001: ldc.i4.0
L_0002: stloc.1

//使用newobj指令创建新的对象,并调用构造函数以0x76(123的16进制)初始化
L_0003: ldc.i4.s 0x7b
L_0005: newobj instance void Anytao.net.My_Must_net._05_new.MyClass::.ctor(int32)
L_000a: stloc.2
//加载“My Struct”
L_000b: ldloca.s struct2
L_000d: ldstr "My Struct"
//调用构造函数执行初始化
L_0012: call instance void Anytao.net.My_Must_net._05_new.MyStruct::.ctor(string)
L_0017: nop
L_0018: ret
}

从而可以得出以下结论:

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关键字和其本质的来龙去脉能有所帮助。

言归正传,开篇的几个题目,不知读者是否有了各自的答案,我们不妨畅所欲言,做更深入的讨论,以便揭开其真实的面纱。

参考文献

(USA)Stanley B.Lippman, C# Primer

(USA)David Chappell Understanding .NET




广而告之

[预告]

另外鉴于前几个主题的讨论中,不管是类型、关键字等都涉及到引用类型和值类型的话题,我将于近期发表相关内容的探讨,同时还有其他的关键字值得研究,这是本系列近期动向,给自己做个广告。祝各位愉快。

[声明]

本文的关键字new指的是C#中的关键字概念,并非一般意义上的.NET CRL范畴,之所以将这个主题加入本系列,是基于在.NET体系下开发的我们,何言能逃得过基本语言的只是要点。所以大可不必追究什么是.NET,什么是C#的话题,希望大家理清概念,有的放肆。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐