(五) 类型设计(随笔)

一、类型成员及访问限定

       1. 类成员

              一个类型可以包含零个或者多个一下成员:

              常数:一个恒定不变的数值符号,增强程序可读性与可维护性,静态的。

              字段:可读可写,也可以是自读,建议设置为私有,防止类型外的代码破坏。

             实例构造器:特殊方法,用来将新对象实例字段初始化到正常的初始化状态。

             类型构造器:特殊字段,用来将新对象静态字段初始化

             其他略

        2.访问限定修饰符与预定义特性

             C# 默认是 Internal;

              类型预定义特性:abstract(不被实例化),sealed(不被继承);

             字段预定义特性:static(字段是类型状态),readonly(字段仅在构造器中被赋值);

            方法预定义特性:static(类型状态,对对象状态一无所知)

                                            virtual(继承链最末端方法被调用 )

                                             new(不重写基类中的虚方法,仅仅是将其隐藏起来,仅应用与虚方法)

                                            override(显式表明方法在重写基类虚方法)

                                            abstract(表示派生类比较提供和该抽象方法签名一样的实现)

                                             sealed(派生方法不能重写该方法,仅应用与虚方法)   

二、常数与字段

       1. 常数

              必须是基元类型,编译时确定他的值,存放在托管模块的元数据中,是类型而非实例的一部分。不占用任何内存分配(直接嵌入到IL代码中);

              常数隐形是static,所以C#不允许给常数家静态关键字

              public const int a =23;

       2. 字段

               类型字段,系统在该类型被加载到应用程序域是为其分配内存地址,通常发生在该类型的方法第一次被JIT编译时;

               实例字段,系统在该类型实例被构建时为其分配内存地址。

               字段是动态内存地址存储,只能在运行时获取其值。


              实例只读字段只能在实例构造器被赋值,实例初始化后执行,且执行一次;

              静态只读字段只能在类型构造器中赋值,执行。

             很多字段都是以内联方式进行初始化,实际上是在构造器中初始化的。             

三、方法

      1. 实例构造器

            创建引用类型的实例,步骤:

                  首先为实例分配内存,初始化实例的附加成员,最后调用类型的实例构造器设置对象的初始状态。

             每个实例构造器都会初始化字段,必须防止代码膨胀(设置一个显式初始化的构造器,其他构造器使用显式构造器初始化,有利的减少了代码)

             值类型的构造器只有被显式调用时,才会执行。C#根本就不允许我们定义一个值类型的无参构造器。    

      2.类型构造器

               类型构造器,默认情况没有定义,要定义也只能定义一个,并且是无参构造器。static,私有;值类型与应用类型都具有。

               调用时机:

                        在类型的一个实例对象创建之前,或者在类型的第一个非继承的字段或者成员第一次访问之前;

                        在非继承静态字段被第一次访问之前的某个时刻;

               类型构造函数不应调用基类构造函数;基类的静态字段并没有被派生类型继承。静态字段,静态方法,静态属性等都不会被继承,而是编译时静态绑定。

               执行顺序:

                       首先产生初始化静态字段所需的代码,然后才是类型构造方法中显式的代码转换。与实例构造器执行顺序一致。                

      3.操作法重载方法               

      4.转换操作符方法

              隐性转换操作符:Implicit Operator  类型A(int a);类型A aa = 3;

              显性转换操作符:explicit Operator 类型Int(类型A a); int aa = (int)类型A 对象;                          

      5. 引用参数

            默认情况,CLR都是认为参数都是值传递;引用类型是传递引用或者指针(也是引用或者指针本身也是按值传递的);

           对于值类型实例的参数,传递给方法的将是值类型实例的一份拷贝,意味着方法得到了属于他自己的值类型实例的拷贝;使用Out和Ref 关键字告诉编译器需要按照引用方式处理(即传入的是地址)。

             Out 不需要再方法体外就被初始化,并且方法不能直接读取该参数的值,还必须返回前给其赋值;(输出)

             Ref 需要在方法体外被初始化,方法体可以选择读取或者赋值操作。

            不能通过Out与Ref来区别重载,因为其编译后代码一样。但是运行Out,Ref 与不带这两个关键字的方法重载。

      6.可变数目参数

             static Int32 Add(parmas  Int32[ ] valuse);

              Add(1,2,3,4);//编译通过

             parmas 告诉编译器在指定的参数上应用一个System. ParmaArrayAttribute定制特性的实例。  

      7.虚方法的调用机理

            call:根据引用变量的类型(引用变量的静态类型,声明类型)来调用一个方法;

          callvirt:根据引用变量指向的对象类型(引用变量的动态类型,实际类型);

      8.虚方法的版本问题

               使用new, 告诉编译器,子类方法与基类没有关系;    

               使用override,告诉编译器,子类方法与基类方法相关;虚函数执行时,总是调用继承链中最后的实现。 

四、属性

        属性又叫索引器

       1. 无参属性

        2.含参属性

五、事件

        定义了事件成员的类型运行类型(类型的实例)在某些特定事情发生的时候通知其他对象。

         定义事件成员意味着类型为我们提供了一下三种能力:

                 允许对象登记该事件;

                 允许对象注销该事件; 

                 允许定义事件的对象维护一个登记对象的集合,在事件发生时通知这些对象;

           CLR事件机制是建立在委托机制上的,使用委托的回调机制。

      1.发布事件

             定义一个类型用于保存消息内容:

                    按约定需要继承 System.EventArgs,并且命名以EventArgs结束。

              定义一个委托类型,用于指定事件触发时被调用的函数原型:

                    按约定需要以 EventHandler结束,void 返回值,object,EventArgs 参数。

             定义一个事件成员:

                      event  委托名 mailmsg   

               定义一个受保护的虚方法,负责通知登记对象

                      OnMailMsg,如果有事件,则触发事件Mailmsg;

             定义一个方法,将输入转化成期望的事件:

               event 编译器翻译成三个构造:

                     构造一个私有委托,指向null;

                    构造一个添加方法;

                   构造一个删除方法;   

                     (五) 类型设计(随笔)_第1张图片         

       2.侦听事件

             +=操作符:  登记事件;(编译器提供了内置的事件支持  add_事件);

              -=操作:    删除事件                

      3.显式控制事件注册

            (五) 类型设计(随笔)_第2张图片

      4.在一个类型中定义多个事件

               使用EventHandlerset

      5.设计EventHandlerSet类型     (略)

你可能感兴趣的:(.net,框架程序设计)