CLR vir C#之方法

     类和构造函数

     1.当创建一个引用类型的实例时,首先会在内存中分配空间,而后会调用其构造函数对实例进行初始化。元数据中对应构造函数定义:.Ctor.在调用构造函数前,字段都被初始化为0或者null.

     2.在定义一个类的时候,默认有一个无参的构造函数存在。也可以定义多个参数不同的构造函数。当调用构造函数时候,它会首先自动调用基类构造函数,直至System.Object的构造函数(一个无参,什么都不做的构造函数)

     3.在类中定义一个字段

Code
     利用Reflector工具可以看到:
Code

     编译器会自动在其无参构造函数中对其赋值,也有中叫法,这种方法为“内联代码”(inline)

     所以,通常我们定义的字段都要在构造函数中赋值。

Code

     注意,其中利用this关键字,可以在一个构造函数调用另一个构造函数。

     结构体和构造函数

     1.结构体没有默认的构造函数,所以象上述那样定义字段,是不可行的(找不到构造函数)。

     2.在C#中也不能显式的定义无参构造函数。(CLR中允许)

     3.一旦为结构体定义构造函数,必须在构造函数中给所有的字段初始化。

     

Code

 

     静态构造函数

     1.静态构造函数默认Private,并且不能显式定义其访问级别。

     2.通常在静态构造函数中初始化静态变量

     3.静态构造函数只在类型第一个被调用加载时执行,且只执行一次。

     4.对应元数据定义 .cctor

     5.如下定义:

Code

    对应元数据:

Code

     此时也会自动生成一个静态构造函数,并在其中进行赋值。

     6.静态构造函数不会调用基类的静态构造函数。

     7.通常我们也会这样定义:

Code

     那么这种方式和原来的方式有什么区别呢?(引)
     精确语义Precise:针对在cctor中初始化而言();
     字段初始化前语义BeforeFieldInit:针对于内联初始化而言。
     二者的区别在于是否会在MSIL中的cctor上附加一个BeforeFieldInit标记

     性能测试:

Code

     运行结果:
PerfTest1:00:00:03.2077364 BeforeFieldInit
PerfTest1:00:00:07.6219642 Precise
PerfTest2 :00:00:03.2216907 BeforeFieldInit
PerfTest2:00:00:03.2098247 Precise
Press any key to continue . . .

     可见:第一此执行时,内联方式要比精确定义方式要得多,但是之后,就差不多了。

     运算符重载

     如下定义:

Code
      IL:
Code

     可以看到,IL中对此方法有几个特殊标记:specialname , op_XXX.

     当此运算符被调用时,编译器会查找是否有specialname标记的方法存在,如果存在在检查方法参数是否有一个是所在类型别,如果确认正确则调用,否则异常。

     应用可见:
     http://www.cnblogs.com/Ivan-Yan/archive/2008/06/11/1217436.html
     自定义数据类型转换:

     http://blog.csdn.net/JustLovePro/archive/2008/09/08/2900548.aspx

     通过引用方式给方法传参(out,ref)

     关键字告诉CLR,参数以引用的方式传递。CLR对两个关键字的处理是一致的,但是C#编译器则不同:

     1.采用out方式传递,传递前不必初始化。但是在方法返回之前必须给其赋值。

     2.采用ref方式传递,必须初始化。在方法内部可读可写。

     给方法传递可变数目的参数(paras)

     1.paras关键字只能位于方法最后一个参数位置。

     2.paras关键字告诉编译器参数应用了个定制特性System.ParamArrayAttribute。当调用一个方法时,编译器首先查找不含这个特性的方法中有没有合适的方法可悲调用,如果没有,在检查包含此特性的方法是否适合参数化调用。

     3.必须是一个一维数组,可以传null,或者不传。

     4.也经常采用方法的重载来实现可以提高性能(参数的传递设计数据的copy,内存分配,比较消耗性能)

     声明方法的参数类型(引)

     原则1:方法参数尽可能指定为最弱的类型
    选用IEnumberable<T>,而不是IList<T>或ICollection<T>
     原则2:方法返回类型尽可能指定为最强的类型
    返回FileStream,而不是Stream
     原则3:如果希望在不影响调用代码的情况下,能对方法内部实现进行修改,这时候返回类型要使用最弱类型中的最强的一个。
    使用IList<T> ,而不是List<T>

你可能感兴趣的:(C#)