const 与readonly
const 关键字用于修改字段或局部变量的声明。它指定字段或局部变量的值不能被修改。常数声明引入给定类型的一个或多个常数。
常数声明可以声明多个常数,例如:public const double x = 1.0, y = 2.0, z = 3.0;
不允许在常数声明中使用 static 修饰符。
常数可以参与常数表达式,例如:public const int c1 = 5.0;public const int c2 = c1 + 100;
const 关键字用于修改字段或局部变量的声明。它指定字段或局部变量的值不能被修改。常数声明引入给定类型的一个或多个常数。
常数声明可以声明多个常数,例如:public const double x = 1.0, y = 2.0, z = 3.0;
不允许在常数声明中使用 static 修饰符。
常数可以参与常数表达式,例如:public const int c1 = 5.0;public const int c2 = c1 + 100;
readonly 关键字是可以在字段上使用的修饰符。当字段声明包括 readonly 修饰符时,该声明引入的字段赋值只能作为声明的一部分发生,或者发生在同一类的构造函数中。
当在声明中初始化变量时,例如: public readonly int y = 5;
对于实例字段,在包含字段声明的类的实例构造函数中;或者,对于静态字段,在包含字段声明的类的静态构造函数中。只有在这些上下文中时,将 readonly 字段传递为 out 或 ref 参数才有效。
当在声明中初始化变量时,例如: public readonly int y = 5;
对于实例字段,在包含字段声明的类的实例构造函数中;或者,对于静态字段,在包含字段声明的类的静态构造函数中。只有在这些上下文中时,将 readonly 字段传递为 out 或 ref 参数才有效。
readonly 关键字与 const 关键字不同。const 字段只能在该字段的声明中初始化。readonly 字段可以在声明或构造函数中初始化。因此,根据所使用的构造函数,readonly 字段可能具有不同的值。另外,const 字段是编译时常数,而 readonly 字段可用于运行时常数,如下例所示:public static readonly uint l1 = (uint) DateTime.Now.Ticks;
析构函数
析构函数用于销毁类的实例。
不能对结构使用析构函数,只能对类使用析构函数。
一个类只能有一个析构函数。
无法继承或重载析构函数。
无法调用析构函数,它们是被自动调用的。
析构函数既没有修饰符,也没有参数。
析构函数隐式地对对象的基类调用 Object.Finalize 方法,进行垃圾回收。
无法控制何时调用析构函数,因为这由垃圾回收器决定的。垃圾回收器检查是否存在应用程序不再使用的对象。它认为这些对象符合销毁条件并回收这些对象占用的内存。程序退出时也会调用析构函数。
可以通过调用 GC.Collect 方法强制进行垃圾回收,但大多数情况下应避免这样做,因为这样会导致出现性能问题。
在派生类中,按照从派生相近程度最大的到派生相近程度最小的次序调用,既最底层的派生类的析构函数首先被调用,然后逐个基类的析构函数被调用。
.NET Framework 垃圾回收器会隐式地管理对象的内存分配和释放。但是,当应用程序封装窗口、文件和网络连接这类非托管资源时,应当使用析构函数释放这些资源。
如果应用程序在使用昂贵的外部资源,可通过实现 Dispose 方法(来自 IDisposable 接口)对象执行必要的清理,在垃圾回收器释放对象前显式地释放资源的方式。即使有这种对资源的显式控制,析构函数也是一种保护措施,可用来在对 Dispose 方法的调用失败时清理资源。
析构函数用于销毁类的实例。
不能对结构使用析构函数,只能对类使用析构函数。
一个类只能有一个析构函数。
无法继承或重载析构函数。
无法调用析构函数,它们是被自动调用的。
析构函数既没有修饰符,也没有参数。
析构函数隐式地对对象的基类调用 Object.Finalize 方法,进行垃圾回收。
无法控制何时调用析构函数,因为这由垃圾回收器决定的。垃圾回收器检查是否存在应用程序不再使用的对象。它认为这些对象符合销毁条件并回收这些对象占用的内存。程序退出时也会调用析构函数。
可以通过调用 GC.Collect 方法强制进行垃圾回收,但大多数情况下应避免这样做,因为这样会导致出现性能问题。
在派生类中,按照从派生相近程度最大的到派生相近程度最小的次序调用,既最底层的派生类的析构函数首先被调用,然后逐个基类的析构函数被调用。
.NET Framework 垃圾回收器会隐式地管理对象的内存分配和释放。但是,当应用程序封装窗口、文件和网络连接这类非托管资源时,应当使用析构函数释放这些资源。
如果应用程序在使用昂贵的外部资源,可通过实现 Dispose 方法(来自 IDisposable 接口)对象执行必要的清理,在垃圾回收器释放对象前显式地释放资源的方式。即使有这种对资源的显式控制,析构函数也是一种保护措施,可用来在对 Dispose 方法的调用失败时清理资源。
虚拟方法
若一个实例方法的声明中含有 virtual 修饰符,则称该方法为虚拟方法。若其中没有 virtual 修饰符,则称该方法为非虚拟方法。
几乎所有的基类都包含虚拟方法。如果一个类不包含虚拟方法,则表示它将不作为一个基类使用,但并是不绝对。
虚拟方法的目的就是让派生类去定制自己的行为。
非虚拟方法,无论是在声明它的类的实例上调用该方法还是在派生类的实例上调用,实现都是相同的。
一个虚拟方法的实现可以由派生类取代。取代所继承的虚拟方法的实现的过程称为重写该方法。
若一个实例方法的声明中含有 virtual 修饰符,则称该方法为虚拟方法。若其中没有 virtual 修饰符,则称该方法为非虚拟方法。
几乎所有的基类都包含虚拟方法。如果一个类不包含虚拟方法,则表示它将不作为一个基类使用,但并是不绝对。
虚拟方法的目的就是让派生类去定制自己的行为。
非虚拟方法,无论是在声明它的类的实例上调用该方法还是在派生类的实例上调用,实现都是相同的。
一个虚拟方法的实现可以由派生类取代。取代所继承的虚拟方法的实现的过程称为重写该方法。