请参见
三种类构造函数:
类构造函数的类型 注释 实例 用于创建并初始化类的实例。 私有 在类之外不可访问的特殊类型实例构造函数。无法用私有构造函数来实例化类。 静态 在创建第一个实例或引用任何静态成员之前,将自动调用这种构造函数来初始化类。无法直接调用这种构造函数。
请参见
三种类构造函数:
类构造函数的类型 | 注释 |
---|---|
实例 | 用于创建并初始化类的实例。 |
私有 | 在类之外不可访问的特殊类型实例构造函数。无法用私有构造函数来实例化类。 |
静态 | 在创建第一个实例或引用任何静态成员之前,将自动调用这种构造函数来初始化类。无法直接调用这种构造函数。 |
一. 静态构造函数
静态构造函数用于初始化类。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类。静态构造函数是通过下面的形式来声明的:
[attributes] static identifier( ) { constructor-body }
其中:
-
attributes(可选)
- 附加的声明性信息。有关属性和属性类的更多信息,请参见 C# 属性。 identifier
- identifier 与类名相同。 constructor-body
- 包含初始化类的语句的块。
备注
静态构造函数既没有访问修饰符,也没有参数。
在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类。
无法直接调用静态构造函数。
在程序中,用户无法控制何时执行静态构造函数。
静态构造函数的典型用途是:当类使用日志文件时,将使用这种构造函数向日志文件中写入项。
示例
在此示例中,类 MyClass
有一个静态构造函数和一个静态成员 MyMethod()
。当调用 MyMethod()
时,将调用静态构造函数来初始化类。
// StaticCtor1.cs using System; class MyClass { // Static constructor: static MyClass() { Console.WriteLine("The static constructor invoked."); } public static void MyMethod() { Console.WriteLine("MyMethod invoked."); } } class MainClass { static void Main() { MyClass.MyMethod(); } }
输出
The static constructor invoked. MyMethod invoked.
二. 私有构造函数
私有构造函数是一种特殊的实例构造函数。它通常用在只包含静态成员的类中。如果类具有一个或多个私有构造函数而没有公共构造函数,则不允许其他类(除了嵌套类)创建该类的实例。例如:
class NLog
{
// Private Constructor:
private NLog() {}
public static double e = 2.71828;
}
声明空构造函数可阻止自动生成默认构造函数。注意,如果您不对构造函数使用访问修饰符,则在默认情况下它仍为私有构造函数。但是,通常显式地使用 private(私有)修饰符来清楚地表明该类不能被实例化。
当没有实例字段或实例方法(如 Math 类)或调用方法以获得类的实例时,私有构造函数可用于阻止创建类。
示例
下面是使用私有构造函数的类的示例。
// PrivateCtor1.cs
using System;
public class MyClass
{
private MyClass() {}
public static int counter;
public static int IncrementCounter()
{
return ++counter;
}
}
class MainClass
{
static void Main()
{
// If you uncomment the following statement, it will generate
// an error because the constructor is inaccessible:
// MyClass myObject = new MyClass(); // Error
MyClass.counter = 100;
MyClass.IncrementCounter();
Console.WriteLine("New count: {0}", MyClass.counter);
}
}
输出
New count: 101
注意,如果您取消注释该示例中的以下语句,它将生成一个错误,因为该构造函数受其保护级别的限制而不可访问:
// MyClass myObject = new MyClass(); // error
实例构造函数用于创建和初始化实例。构造函数是通过下面的形式声明的:
[attributes] [modifiers] identifier([formal-parameter-list]) [initializer] { constructor-body }
其中:
-
attributes(可选)
- 附加的声明性信息。有关属性和属性类的更多信息,请参见 C# 属性 。 modifiers(可选)
- 允许的修饰符为 extern 和四个 访问修饰符 。 identifier
- identifier 与类名相同。 formal-parameter-list(可选)
- 传递给构造函数的可选参数。参数必须与构造函数本身具有相同的访问保护级别。 initializer(可选)
-
在执行构造函数体之前调用。initializer 可以是以下带有可选的 argument-list 的两者之一:
: base (argument-list)
: this (argument-list)
constructor-body
- 包含初始化类实例的语句的块。
备注
创建新对象时将调用类构造函数,例如:
Point myPoint = new Point();
一个类可以有多个构造函数。例如,可以声明一个不带参数的构造函数(如 Point()
)和一个带参数的构造函数(如 Point(int x, int y)
)。
如果类没有构造函数,将自动生成一个默认的无参数构造函数,并使用默认值初始化对象字段(例如,int 将初始化为 0)。有关默认值的更多信息,请参见默认值表。
类构造函数可通过初始值设定项来调用基类的构造函数,例如:
public Cylinder(double radius, double height): base(radius, height) { }
在前面的示例中,字段 radius 和 height 都是通过基类构造函数初始化的。这类似于 C++ 的初始化列表。
类构造函数也可通过关键字 this 调用同一个类的另一个构造函数,例如:
public Point(): this(0,20) { }
在前面的示例中,无参数构造函数 Point() 调用了另一个带有两个参数的构造函数,将默认位置初始化为 (0, 20)。
示例 1
下面的示例说明包含两个类构造函数的类:一个类构造函数没有参数,另一个类构造函数带有两个参数。
// Constructor1.cs using System; class Point { public int x, y; // Default constructor: public Point() { x = 0; y = 0; } // A constructor with two arguments: public Point(int x, int y) { this.x = x; this.y = y; } // Override the ToString method: public override string ToString() { return(String.Format("({0},{1})", x, y)); } } class MainClass { static void Main() { Point p1 = new Point(); Point p2 = new Point(5,3); // Display the results using the overriden ToString method: Console.WriteLine("Point #1 at {0}", p1); Console.WriteLine("Point #2 at {0}", p2); } }
输出
Point #1 at (0,0) Point #2 at (5,3)
示例 2
在此示例中,类 Person
没有任何构造函数;在这种情况下,将自动提供默认构造函数,同时将字段初始化为它们的默认值。
// Constructor2.cs using System; public class Person { public int age; public string name; } public class MainClass { static void Main() { Person p = new Person(); Console.Write("Name: {0}, Age: {1}",p.name, p.age); } }
输出
Name: , Age: 0
注意,age
的默认值为 0
,name
的默认值为 null。有关默认值的更多信息,请参见默认值表。
示例 3
下面的示例说明使用基类初始值设定项。Circle
类是从通用类 Shape
派生的,Cylinder
类是从 Circle
类派生的。每个派生类的构造函数都使用其基类的初始值设定项。
// CtorInitializer.cs using System; abstract class Shape { public const double pi = Math.PI; protected double x, y, z; public Shape (double x, double y, double z) { this.x = x; this.y = y; this.z = z; } public abstract double Area(); } class Circle: Shape { public Circle(double radius): base(radius,0,0) { } public override double Area() { return pi*x*x; } } class Cylinder: Circle { public Cylinder(double radius, double height): base(radius) { y = height; } public override double Area() { return 2*(base.Area()) + 2*pi*x*y; } } class TestClass { public static void Main() { double radius = 2.5, height = 3.0; Circle myCircle = new Circle(radius); Cylinder myCylinder = new Cylinder(radius, height); Console.WriteLine("Area of the circle = {0:F2}", myCircle.Area()); Console.WriteLine("Area of the cylinder = {0:F2}", myCylinder.Area()); } }
输出
Area of the circle = 19.63 Area of the cylinder = 86.39