1:构造函数中的base
构造函数可以使用 base 关键字来调用基类的构造函数。例如:
public class Manager : Employee { public Manager(int annualSalary) : base(annualSalary) { //Add further instructions here. } } 在派生类中,如果不使用 base 关键字来显式调用基类构造函数,则将隐式调用默认构造函数(如果有的话)。这意味着下面的构造函数声明在效果上是相同的: public Manager(int initialdata) { //Add further instructions here. } public Manager(int initialdata) : base() { //Add further instructions here. }
2:构造函数中的this
构造函数可以使用 this 关键字调用同一对象中的另一构造函数。和 base 一样,this 可带参数使用也可不带参数使用,构造函数中的任何参数都可用作 this 的参数,或者用作表达式的一部分。
3:static构造函数
使用 static 关键字可以将构造函数声明为静态构造函数。在访问任何静态字段之前,都将自动调用静态构造函数,它们通常用于初始化静态类成员。
使用 new 表达式创建某个类的对象时,会使用实例构造函数创建和初始化所有实例成员变量。要初始化静态类或非静态类中的静态变量,必须定义静态构造函数。
在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。
静态构造函数具有以下特点:
• 静态构造函数既没有访问修饰符,也没有参数。
• 在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类。
• 无法直接调用静态构造函数。
• 在程序中,用户无法控制何时执行静态构造函数。
• 静态构造函数的典型用途是:当类使用日志文件时,将使用这种构造函数向日志文件中写入项。
• 静态构造函数在为非托管代码创建包装类时也很有用,此时该构造函数可以调用 LoadLibrary 方法。
• 如果静态构造函数引发异常,运行时将不会再次调用该构造函数,并且在程序运行所在的应用程序域的生存期内,类型将保持未初始化。
4:private构造函数
通过将构造函数设置为私有构造函数,可以阻止类被实例化。
私有构造函数是一种特殊的实例构造函数。它通常用在只包含静态成员的类中。如果类具有一个或多个私有构造函数而没有公共构造函数,则其他类(除嵌套类外)无法创建该类的实例。
• 不能在结构中定义析构函数。只能对类使用析构函数。
• 一个类只能有一个析构函数。
• 无法继承或重载析构函数。
• 无法调用析构函数。它们是被自动调用的。
• 析构函数既没有修饰符,也没有参数。
5:析构函数
下面是类 Car 的析构函数的声明:
class Car { ~Car() // destructor { // cleanup statements... } }
该析构函数隐式地对对象的基类调用 Finalize。这样,前面的析构函数代码被隐式地转换为以下代码:
protected override void Finalize() { try { // Cleanup statements...} finally { base.Finalize(); } }
这意味着对继承链中的所有实例递归地调用 Finalize 方法(从派生程度最大的到派生程度最小的)。
不应使用空析构函数。如果类包含析构函数,Finalize 队列中则会创建一个项。调用析构函数时,将调用垃圾回收器来处理该队列。如果析构函数为空,只会导致不必要的性能损失。
6:释放资源(实现Dispose方法)
由析构函数执行的资源释放,是由垃圾回收器决定的。
如果您的应用程序在使用昂贵的外部资源,我们还建议您提供一种在垃圾回收器释放对象前显式地释放资源的方式。可通过实现来自 IDisposable 接口的 Dispose 方法来完成这一点,该方法为对象执行必要的清理。这样可大大提高应用程序的性能。
类型的 Dispose 方法应释放它拥有的所有资源。 它还应该通过调用其父类型的 Dispose 方法释放其基类型拥有的所有资源。 父类型的 Dispose 方法应该释放它拥有的所有资源,进而调用其父类型的 Dispose 方法,从而在整个基类型层次结构中传播此模式。 若要帮助确保始终正确地清理资源,Dispose 方法应该可以多次调用而不引发异常。
7:何时实现Dispose方法
对只使用托管资源的类型(如数组)实现 Dispose 方法并不能提高性能,原因是这些类型由垃圾回收器自动回收。 应主要对使用本机资源的托管对象和向 .NET Framework 公开的 COM 对象使用 Dispose 方法。方法是实现IDisposable接口。
下面的代码示例演示为封装非托管资源的类实现 Dispose 方法的建议设计模式。
资源类通常是从复杂的本机类或 API 派生的,而且必须进行相应的自定义。 使用这一代码模式作为创建资源类的一个起始点,并根据封装的资源提供必要的自定义。
using System; using System.IO; class Program { static void Main() { try { // Initialize a Stream resource to pass // to the DisposableResource class. Console.Write("Enter filename and its path: "); string fileSpec = Console.ReadLine(); FileStream fs = File.OpenRead(fileSpec); DisposableResource TestObj = new DisposableResource(fs); // Use the resource. TestObj.DoSomethingWithResource(); // Dispose the resource. TestObj.Dispose(); } catch (FileNotFoundException e) { Console.WriteLine(e.Message); } } } // This class shows how to use a disposable resource. // The resource is first initialized and passed to // the constructor, but it could also be // initialized in the constructor. // The lifetime of the resource does not // exceed the lifetime of this instance. // This type does not need a finalizer because it does not // directly create a native resource like a file handle // or memory in the unmanaged heap. public class DisposableResource : IDisposable { private Stream _resource; private bool _disposed; // The stream passed to the constructor // must be readable and not null. public DisposableResource(Stream stream) { if (stream == null) throw new ArgumentNullException("Stream in null."); if (!stream.CanRead) throw new ArgumentException("Stream must be readable."); _resource = stream; _disposed = false; } // Demonstrates using the resource. // It must not be already disposed. public void DoSomethingWithResource() { if (_disposed) throw new ObjectDisposedException("Resource was disposed."); // Show the number of bytes. int numBytes = (int) _resource.Length; Console.WriteLine("Number of bytes: {0}", numBytes.ToString()); } public void Dispose() { Dispose(true); // Use SupressFinalize in case a subclass // of this type implements a finalizer. GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // If you need thread safety, use a lock around these // operations, as well as in your methods that use the resource. if (!_disposed) { if (disposing) { if (_resource != null) _resource.Dispose(); Console.WriteLine("Object disposed."); } // Indicate that the instance has been disposed. _resource = null; _disposed = true; } } }
8:使用using
using 语句确保调用 Dispose,即使在调用对象上的方法时发生异常也是如此。通过将对象放入 try 块中,并在调用 finally 块中的 Dispose,可以获得相同的结果;实际上,这就是编译器转换 using 语句的方式。
练习:
1:举例说明如何在子类构造函数中调用父类构造函数
2:public Manager(int initialdata)
{
//Add further instructions here.
}
public Manager(int initialdata)
: base()
{
//Add further instructions here.
}
这两个构造函数有没有区别,如果有区别,在哪里?
3:public Manager(int initialdata)
{
//Add further instructions here.
}
public Manager(int initialdata)
: base(initialdata)
{
//Add further instructions here.
}
这两个构造函数有没有区别,如果有区别,在哪里?
4:public Manager(int initialdata)
: this()
{
//Add further instructions here.
}
这样子使用this可以不可以,如果可以,则表示什么意思?
5:你觉得在哪种情况下需要使用private构造函数,提示:某种设计模式。
6:如何实现Dispose方法。
7:实现Dispose方法有什么用。提示:答释放资源为0分。
8:using的几种用法。