Visual Basic .NET Power Coding 读书笔记之第一章 基本语言构造

 

第一章       基本语言构造

一、      值类型和引用类型

.Net中的每种类型(包括Integer这样的类型和EventLog类)都是从Object类派生出来的。这意味着每种类型都具有方法:“构造函数”、EqualsGetHashCodeGetTypeReference-EqualsToStringFinalizeMemberwiseClone等。

值类型完全从System.ValueType派生的。从ValueType派生的是“结构”,不从ValueType派生的是类。ValueType派生类的创建通常不会调用构造函数,而且属于较简单类型。

更重要的是,值类型是轻量型的,它并不承载Run Time Type Information(运行时类型信息,RTTI),也就是.Net中所谓的类型信息;而引用类型则带有类型信息。

值类型获取类型时会发生一个名为“装箱”(Box)的过程。

1、        结构

结构能够定义常量、枚举类型、字段、属性、方法和事件。从一定程度上讲,结构可以被看作类,但不带有类型信息(除非需要),不需要(但支持)使用构造函数,而且不能被继承。

 

结构与类的差别:

1)        结构是值类型,类是引用类型。

2)        结构使用堆栈内存空间,类使用堆内存空间。

3)        结构成员默认为公共类型,类字段和常量默认为私有类型,其它的类成员默认是公共类型。

4)        只有类成员可以声明为保护类型。在结构是不支持Protected这种访问修饰符。

5)        结构中的方法不能处理事件。

6)        结构中的字段不能被指定初始值。

7)        结构隐式继承类System.ValueType

8)        结构不能继承。

9)        垃圾收集器不为任何结构调用Finalize方法。

10)     在结构中能够定义非共享的构造函数,但构造函数必须带有参数。

 

结构赋值

当结构的实例赋值给一个新的变量时,就生成了该结构的副本。当对结构赋值Null值时,结构中的所有字段被赋为各种类型自身的“空值”。

 

结构相等性校验

在比较结构是否相等时,需要比较每个字段以保证结构具有相同的值。如果只比较结构变量——不是内部字段,那么结果总是不相等的。

2、       

类是引用类型,就是说通过构造函数可在堆上创建类实例。类承载自身相关的RTTI,并且具有面向对象语言要求的所有特征。

类是对类型的“描述”,对象是类型的“实例”。

共享成员在类级别中存在并被对象的所有实例共享。当像对象一样使用一个类时,这个类就被称为“元类”(MetaClass)。

3、        值类型、引用类型和内存

当定义两个值类型并将一个赋值给另一个时,会进行复制。这样就有了两个占据不同内存区域的独立变量。(深复制)

当对两个引用类型进行赋值时会创建一个别名,其名字都将指向同一内存区域。(浅复制)

4、        装箱和拆箱

当需要一个值类型的类型信息时,.NET会对值类型进行装箱。一个明确的“装箱”指令被提交给IL,然后创建一个引用对象,将值类型复制到这个新对象中,并返回类型信息。当请求一个引用类型的代码执行完毕后,IL执行“拆箱”指令。

二、      定义结构和类

1、        垃圾收集

.NET使用的是非确定性内存管理(“确定”表示人去做,“不确定”表示.NET去做)。这当意味着当结束了对象的操作时,将由垃圾收集器决定何时回收内存。非确定性内存管理的含义是可以实现一个析构函数,但是不知道何时它会被调用。

 

析构函数

析构函数实际上是重写了 System.Object 中的虚方法 FinalizeC# 程序中不允许重写此方法或直接调用它(或它的重写)

1.         析构函数是不可继承的,因此,一个类除了自己所声明的析构函数外,一个类不具有其它析构函数。

2.         析构函数要求不能带有参数,因此它不能被重载,因此一个类至多只有一个析构函数。

3.         析构函数是自动调用的,不能被显示调用。

 

实现Dispose方法

.NET中的另一个约定是使用公共方法Dispose,它用于执行确定性的清理。Dispose方法不带参数。

示例:

private bool Disposed;
private void Dispose() 
{
    
if(Disposed)
        
return;

    Disposed 
= true;
    GC.SuppressFinalize(
this);
    
//清理语句
}


如果必须在垃圾收集器之前执行一些特定的清理操作,则用户可以调用Dispose方法。使用布尔值可以防止Dispose方法被调用两次。当进行特别清理时,可以通知垃圾收集器不再需要为该对象运行析构函数。

 

如果希望用户知道类中已经实现了一个Dispose方法,则可以通过实现Idisposable接口达到这个目的。

 

可以调用GC.Collect方法让垃圾收集器运行,但这不是一个推荐的做法。就相当于这么一回事:当孩子把东西弄脏了之后会希望母亲能在身后清理;而如果是想命令妈妈去做,就完全是另一回事了。

2、        使用事件

将一个事件成员添加到类或者结构中,要用到event关键字,后接事件名称和事件处理程序必须具有的方法签名(参数的类型、数量及次序)。

3、        使用访问修饰符

使用访问修饰符的几个规则:

1)      类一般定义成Public:嵌套的类通常定义为Protected或者Private

2)      字段几乎都定义成Private

3)      属性大多数定义成Public,但有时候也定义为Protected

4)      可以对方法使用所有修饰符。要将公共方法的数量保持在最少,每种类型都尽可能少于6个。

5)      事件大多数定义成Public

6)      接口的成员总是Public,并且不能用任何修饰符来直接修饰方法。

7)      不要依赖于默认的权限。尽量使用想要的修饰符来修饰类型成员,而不应该只依赖于默认权限。

如果发现一个类或结构中提供了很多公共成员,则需要判断其内部是否可再细分。如果还可以分解,就要把一种类型分解成多种类型,否则最好让每个成员的访问修饰符都很清楚明确。

三、      理解面向对象思想

1、        对象、类、元类

“类”描述事物,而“对象”是那些事物的实例

元类是可以“像对象一样使用”的类。

2、        信息隐藏和封装

将字段、属性、方法和事件定义为类型成员被称为封装,可以说类型封装了成员。封装处理了部分和整体的概念,成员是类型整体的组成部分。

当使用访问修饰符对类的用户在逻辑上隐藏成员时,被称作为“信息隐藏”。

3、        关联、聚集和继承

“关联”指一种关系,这种关系为一个对象指向另一个对象的实例,但不负责创建那个对象。单向关联表示只能是其中一个类识别另外一个,而双向关联表示关系中的双方对象都可以相互识别,但彼此都不负责创建对象。

“聚集”与包含相关。当一个对象饮食对另一个对象的引用,并且负责创建该对象,就称之为聚集(有时也被称为复合(Composition))。

“继承”指一个类拥有另一个类的成员,被继承的类称为“父类”或“超类”,而继承得到的类则被称为“子类”。

4、        多态

“多态”与继承有关。多态的基础是无需知道一个对象的类型就能对其执行正确的操作。理论含义就是能够定义同大多数普通类型交互的方法,并且当这些类型被一个更特殊的类型表示时,方法也能正确执行。技术含义就是,存在一组方法(被编译器创建),称为“虚方法表”,并且存在机器知道如何对这组方法进行索引以找到正确的方法。

posted @ 2005-12-01 10:12  文野  阅读(1460)  评论(0编辑  收藏  举报