现在的位置: 首页 > 综合 > 正文

C#类型定义

2013年02月24日 ⁄ 综合 ⁄ 共 2496字 ⁄ 字号 评论关闭

================
@类型成员及其访问限定
================

一个类型可以定义零或多个一下成员:

1、常数:常熟是一个表示恒定不变的值的符号,这些符号主要用来使得代码更具有可读性和可维护性。常数总是和类型而非它们的实例相关联,它总是静态的。
2、字段:字段是类型的成员变量,它可以是只读或读写的。字段又分为静态和非静态(实例字段),静态字段被视为类型状态的一部分,实例字段被视为对象状态的一部分。
3、实例构造函数:初始化新对对象的实例字段。
4、类型构造函数:初始化类型的静态字段。
5、方法
6、重载操作符
7、转换操作符
8、属性:属性是一种特殊的方法,它使得可以以一种简单的、类似字段的方式设置或获取一个类型或对象的状态,同时可以对其进行保护。
9、事件:事件分为静态事件和实例时间。静态事件通过类型发布通知,通知的接收者可以是一个类型,也可以是一个对象。实例事件通过对象发送通知,通知的接收者同样
     可以是一个类型或者一个对象。
10、类型:类型内部可以嵌套定义其他类型。

访问限定修饰符和预定义特性

应用于类型、字段、方法的访问限定修饰符:
private   类型内部 + 嵌套类
protected   类型内部 + 嵌套类 + 派生类  
Internal   程序集
protected internal  类型内部 + 嵌套类 + 派生类 + 程序集
public   全部

应用于类型的预定义特性:(两者不可同时使用)
abstract   抽象类(不能被实例化)。
sealed   终结类(不可作为基类)。
由于这两者不可同时使用,如果要创建一个既不允许被实例化又不允许被继承的类(比如 Math),就需要为该类指定一个 private 的构造方法。

应用于字段的预定义特性:
static   静态,类型的状态。
readonly   只读。字段仅可以在构造方法中被赋值

应用于方法的预定义特性:
static   静态方法。不能访问类型中的实例字段或实例方法。
virtual   虚方法。当方法被调用时,无论对象是否被转换为基类型,都只有位于对象集成链最末端的方法被调用。仅应用于实例方法。
new   方法的子类实现不会重写基类中的实现,而是将其隐藏。仅应用于虚方法。
override   显式表明方法重写了基类型中的虚方法。仅应用于虚方法。
abstract   表示派生类型必须提供和该抽象方法签名匹配的实现,否则派生类只能为抽象类型。仅应用于虚方法。
sealed   派生类不能重写该方法。仅应用于虚方法。

 ===========
@常数与字段
===========

常数的类型必须是那些编译器认为的基类型,其总是被认为是类型(而非实例)的一部分,因此常数默认是静态(static)的。
只读字段可以是引用类型,且不会像常数那样产生版本问题。实例只读字段可以在构造函数中进行初始化。

======
@方法
======
1、实例构造函数:
     在创建一个类型的实例时,系统将首先为该实例分配内存,然后初始化对象的附加成员(方法表指针和一个SyncBlockIndex),最后调用类型的实例构造函数进行初始化。
     当构造一个引用类型的实例时,调用构造函数前,系统会将所有没有显示赋值的字段赋予 0 值或 null。
     一个类型的实例构造函数在调用其基类的继承字段之前,必须调用其基类的实例构造函数。C#编译器会自动产生对基类默认构造函数的调用代码。
2、类型构造函数必须指定为 static,且总是私有方式(无需指定 private)。
     类型构造函数的调用时间:在类型第一个实例被创建之前,或者在类型的非继承字段或成员第一次被访问之前(just before)或者之前的某个时刻。
     类型构造函数不应该调用其基类型的类型构造函数,因为基类型的静态字段并没有被派生类继承,其方式是静态绑定。
3、虚方法调用
 
【实验步骤】

@定义常数字段、只读字段

///////////////////////////////////////////////////////////////////////////

// Test.cs
using System;
public class Test{
 public static void Main(){
  Console.WriteLine("num is : " + A.num);
 }
}

// A.cs
public class A{
 public const int num = 5;
}

///////////////////////////////////////////////////////////////////////////

D:\mytest>csc /t:library A.cs
D:\mytest>csc /r:A.dll test.cs
D:\mytest>test
num is : 5

删除 A.dll 文件后仍可正常运行。
D:\mytest>test
num is : 5

但不可以编译。
D:\mytest>csc /r:A.dll test.cs
error CS0006: 未能找到元数据文件“A.dll”

将 A.cs 中 num 值修改为 10 重新编译 A.cs。然后再运行:
D:\mytest>test
num is : 5

显然这里使用常数会产生版本问题,如果要获得新的常数值必须重新编译 test.cs。只读字段能够解决这个问题。

修改 A 的定义:

///////////////////////////////////////////////////

public class A{
 public static readonly int num = 5;
}

//////////////////////////////////////////////////

重新编译 A.cs 和 Test.cs 后运行:
D:\mytest>test
num is : 5

将 A.cs 中 num 值修改为 10 重新编译 A.cs。然后再运行:
D:\mytest>test
num is : 10

删除 A.dll
D:\mytest>test
未处理的异常:  System.IO.FileNotFoundException: 未能加载文件或程序集

 

 

 

抱歉!评论已关闭.