一、实例构造器和类(引用类型)
1,极少数情况下可以在不调用实例构造器的前提下创建类型的实例
①Object的MemberwiseClone方法
②运行时序列化器反序列化对象时,通常也不需要调用构造器
internal sealed class SomeType { private Int32 m_x = 5; private String m_s = "Hi"; private Double m_d = 3.14; private byte m_b; public SomeType() { } public SomeType(Int32 x) { } public SomeType(String s) { m_d = 10; } }
由于有三个构造器,所以编译器生成三次初始化m_x,m_s,m_d的代码----每个构造器初始化一次。可以在一个构造器中初始化,让其他构造器都显示调用这个构造器。这样可以减少生成的代码
二、实例构造器和结构(值类型)
①值类型的实例构造器只有显式调用才会执行。
②结构不能包含显式的无参构造函数
③结构中不能有实例字段初始值设定项
internal struct Point{public Int32 m_x, m_y=5;}
④在有参构造函数中必须对所有字段赋值
internal struct Point { public Int32 m_x, m_y; public Point(Int32 x) { //看起来很奇怪,但编译没有问题,会将所有字段初始化为0/null this=new Point(); m_x = x; } }
三、类型构造器
①类型构造器最多只能定义一个。此外,类型构造器永远没有参数
②类型构造器总是私有的
③如果构造器从未执行,JIT编译器会在它生成的本机代码中添加对类型构造器的调用。如果类型构造器已经执行,JIT编译器就不添加对它的调用
④多个线程可能同时执行相同的方法
四、装换操作符方法
implicit:隐式转型。只有在转换不损失精度或数量级的前提下(比如int32转成Rational)
explicit:显示转型。装换会造成精度或数量级的损失(比如将Rational转成int32)
public class a { public a(int i) { } public static a operator +(a a1) { return new a(2); } public static implicit operator a(int i) { return new a(i); } public static implicit operator int(a i) { return 2; } }
五、扩展方法的规则和原则
①C#只支持扩展方法,不支持扩展属性、扩展事件、扩展操作符等
②扩展方法必须在非泛型的静态类中声明
③扩展方法不可以是嵌套类
④为增强性能,并避免找到非你所愿的扩展方法,c#编译器要求“导入”扩展方法
⑤多个静态类可以定义相同的扩展方法,必须显式指定静态类的名称,明确告诉编译器要调用哪个方法
⑥不要将System.Object作为扩展方法的第一个参数