代码改变世界

c#进阶-methods上

2010-12-23 12:47  撞破南墙  阅读(1766)  评论(6编辑  收藏  举报

 构造函数的那些事

如果你不为类定义一个构造函数,他将在编译时候自动产生

public class SomeType { 
}
public class SomeType { 
   public SomeType() : base() { } 
}

两段代码的编译结果一样。

     如果父类是一个抽象类,那么对父类构造函数的访问权限是 protected。

否则是public。如果父类没有提供一个无参构造函数,那么子类必须显示调用父类的构造函数,否则会报错。如果父类是静态的或者是抽象类的,编译器将不对产生默认的构造函数。

    一个类可以定义多个构造函数,但必须得有不同的签名。

一个雷的构造函数必须实现基类的构造函数,否则基类的字段将

不可以访问,(因为字段往往在构造函数中初始化)。所以如果你不显示

调用,C#编译器将会为了自动生成调用一个。到最终来到

SYSTEM.OBJECT中,因为其没有字段,也就没有做什么事。直接返回

 

有时候一个类的创建不用构造函数的来。

比如使用Object’s MemberwiseClone。

比如使用反序列化出一个对象(json/xml等)。

需要注意的:不用在构造函数中调用虚方法,因为如果子类复写的

虚方法中用到还没初始化的字段,将产生不可预料的行为。

看下面一个例子

 

internal sealed class SomeType { 
private Int32 m_x = 5
}

 

 

 

.method public hidebysig specialname rtspecialname 
instance void .ctor() cil managed 

// Code size 14 (0xe) 
.maxstack 8 
IL_0000: ldarg.0 
IL_0001: ldc.i4.5 
IL_0002: stfld int32 SomeType::m_x 
IL_0007: ldarg.0 
IL_0008: call instance void [mscorlib]System.Object::.ctor() 
IL_000d: ret 
}

 

 

从IL中我们知道SomeType 的构造函数中包含

把m_x赋值5的代码 也包含 调用父类 object构造函数的方法。

这说明c#编译器允许你使用内联的方式初始化实例的字段并且放进构造函数中。

internal sealed class SomeType {
private Int32 m_x = 5;

public SomeType(){

m_x=1;

}
}

对于上面的代码是不规范和不安全的,更好的写法是

internal sealed class SomeType {
private Int32 m_x ;

public SomeType(){

m_x=5;

}
}