类型设计

 

7.类型成员及其访问限定

C#中应用于类型、字段、或方法的访问限定修饰符:

Privatepublic;

Protected:所定义及其派生类型中的方法访问,与所在的程序集无关

Internal: 仅被所定义程序集中的方法访问

Protected Internal: 所定义及其派生类型,以及任何定义在同一程序集中方法访问

C#中如果一个非嵌套类型没有显示标识访问限定修饰符,则默认用Internal来标识

 

除了访问限定修饰符外,类型和成员还可以用一些预定义特性来标识。

类型的预定义特性:abstract; sealed(不能作为基类)

方法的预定义特性:static;   virtual;   new;   abstract;   sealed;   override;

 

 

8.常数与字段

常数是一个表示恒定不变的值的符号。定义一个常数类型符号时,需在编译时确定它的值,通过编译后,编译器将值保存在所定义的元数据内。

因为只有基元类型的数据成员才能利用文本常数,在编译时直接进行初始化,而非基元类型的数据成员只能在运行时调用构造器来完成初始化,故常数的类型只能是基元类型。

当使用常数符号时,编译器首先从定义常数的模块的元数据中查找出该符号,直接取出常数的值,然后将之嵌入到编译后产生的IL代码中。常数在运行时不再需要任何的内存分配。

 

字段又称数据成员,它保存着一个值类型的实例、或者一个指向引用类型的引用。

字段是以动态内存的形式存储的,因此只能在运行时获取它们的值。

 

 

9.方法

创建一个引用类型的实例:

1.分配内存

2.初始化对象的附加成员

3.调用类型的实例构造器设置对象的初始状态

当构造一个引用类型实例时,在调用其实例构造器之前,系统为该对象分配的内存总是首先被设为0

默认情况,对于引用类型,编译器会定义一个公有的无参构造器(默认构造器),它允许任何可以访问该类型的代码来构造它的实例。

Class SomeType{

Int32 x=5;

}       //SomeType构造器首先将5赋值给了x,紧接着它又调用了基类的构造器(代码膨胀)

 

class SomeType{

Int32 x=5;

String s=”Hi there”;

public SomeType() {}

public SomeType(Int32 x) {} 

//编译器为以上2个构造器方法产生代码时,每个方法的开始处都将包括初始化x s代码

 

如果我们有一些需要初始化的实例字段和许多重载的构造器方法,应在定义字段时避免同时对它们进行初始化,相反应将这些公共的初始化语句放在一个初始化构造器中,使其他的构造器显示地调用这个初始化构造器。这将有助于减少生成代码的尺寸

Class SomeType{

Int32 x;

String s;

 

Public SomeType() {

X=5;

S=”Hi there”;

}

}

C#编译器不会为值类型自动产生默认的无参构造器;同时,也不允许我们定义无参构造器。

基于性能的考虑,CLR不会尝试为每个包含在引用类型中的值类型字段调用构造器,但会保证值类型中所有的字段都被初始化为0null

C#编译器不允许值类型有无参构造器,但CLR却允许这样

 

Struct SomeType{

Int32 x=5;

}        //error ; C#不允许值类型有无参构造器

 

Struct SomeType{

Int32 x,y;

Public SomeValType(Int32 x){

This.x=x;

}

}        //error; 为值类型定义的任何构造器都必须要初始化其所有的字段

 

类型构造器用于设置一个类型的初始状态,默认情况下,一个类型中没有定义类型构造器,若要定义,也只能定义一个,并且,类型构造器不能有任何参数

class SomeRefType {

         static SomeRefType() {}

}        //访问限制有C#编译器自动设为私有方式

类型构造器的调用总是由CLR负责,调用时间:

1.类型的第一个实例被创建之前

2.非继承静态字段被第一次访问之前

类型构造器不应调用其基类型的类型构造器,因为基类型中的静态字段并没有被派生类型所继承。(注意:静态成员如方法、属性等,不会被派生类型所继承,它们只是编译时静态绑定

CLR来讲,重载操作符仅仅是一些方法而已。

 

当源类型或目标类型不是基元类型时,编译器将不知道如何执行这样的转换;为了使这样的转换成为可能,Rational类型应该定义一些公有的构造器

class Rational{

         public Rational(Int32 numerator) {…}

         public Int32 ToInt32()   {…}

        

         public static implicit operator Rational(Int32 numerator){

                   Return new Rational(value);  

         }

         public static explicit operator Int32(Rational r){

                   Return r.ToInt32();

         }

}

Operator关键字告诉编译器该方法是一个转换操作符,其后,指定对象转型的目标类型,括号内为源类型。Implicit explicit的选择根据精度的丢失与否。

 

posted on 2009-03-02 21:12  Pavel Yu  阅读(631)  评论(0编辑  收藏  举报