使用构造函数 (C# 编程指南)
当实例化类或结构时,运行时会调用其构造函数。 构造函数的名称与类或结构相同,它们通常初始化新对象的数据成员。
在以下示例中,使用简单构造函数定义名为 Taxi
的类。 然后,使用 new
运算符实例化这个类。 运行时在为新对象分配内存后立即调用 Taxi
构造函数。
public class Taxi
{
private string taxiTag;
public Taxi(string tag) => taxiTag = tag;
public override string ToString() => $"Taxi: {taxiTag}";
}
class TestTaxi
{
static void Main()
{
Taxi t = new Taxi("Tag1345");
Console.WriteLine(t);
}
}
不采用任何参数的构造函数称为无参数构造函数new
运算符实例化对象而不给 new
提供任何参数时,运行时将调用无参数构造函数。 C# 12 引入了 主构造函数。 主构造函数指定必须提供用于初始化新对象的参数。 有关详细信息,请参阅 实例构造函数。
除非类 静态,否则没有构造函数的类由 C# 编译器提供公共无参数构造函数,以便启用类实例化。 有关详细信息,请参阅 静态类和静态类成员。
可以通过将构造函数专用化来防止类实例化,如下所示:
class NLog
{
// Private Constructor:
private NLog() { }
public static double e = Math.E; //2.71828...
}
有关详细信息,请参阅私有构造函数。
结构的构造函数 类型类似于类构造函数。 当使用 new
实例化结构类型时,运行时将调用构造函数。 当 struct
设置为其 default
值时,运行时会将结构中的所有内存初始化为 0。 如果在 struct
类型中声明任何字段初始值设定项,则必须提供无参数构造函数。 有关详细信息,请参阅
以下代码对 Int32使用无参数构造函数,以确保整数已初始化:
int i = new int();
Console.WriteLine(i);
但是,以下代码会导致编译器错误,因为它不使用 new
,并且因为它尝试使用未初始化的对象:
int i;
Console.WriteLine(i);
可以初始化或赋值一些 struct
类型(包括所有内置数值类型),然后如以下示例所示使用它们:
int a = 44; // Initialize the value type...
int b;
b = 33; // Or assign it before using it.
Console.WriteLine("{0}, {1}", a, b);
类和结构都可以定义采用参数的构造函数,包括 主构造函数。 必须通过 new
语句或 base 语句调用带参数的构造函数。 类和结构还可以定义多个构造函数,并且无需定义无参数构造函数。 例如:
public class Employee
{
public int Salary;
public Employee() { }
public Employee(int annualSalary) => Salary = annualSalary;
public Employee(int weeklySalary, int numberOfWeeks) => Salary = weeklySalary * numberOfWeeks;
}
可使用下面任一语句创建此类:
Employee e1 = new Employee(30000);
Employee e2 = new Employee(500, 52);
构造函数可以使用 base
关键字调用基类的构造函数。 例如:
public class Manager : Employee
{
public Manager(int annualSalary)
: base(annualSalary)
{
//Add further instructions here.
}
}
在此示例中,基类的构造函数会在执行构造函数的代码块之前被调用。 base
关键字可以带参数或不带参数使用。 构造函数的任何参数都可以用作 base
的参数,也可以用作表达式的一部分。 有关详细信息,请参阅 base。
在派生类中,如果未使用 base
关键字显式调用基类构造函数,则隐式调用无参数构造函数(如果有)。 以下构造函数声明在效果上是相同的:
public Manager(int initialData)
{
//Add further instructions here.
}
public Manager(int initialData)
: base()
{
//Add further instructions here.
}
如果基类不提供无参数构造函数,则派生类必须使用 base
显式调用基构造函数。
构造函数可以使用 this
关键字在同一对象中调用另一个构造函数。 与 base
一样,this
可用于或不使用参数,构造函数中的任何参数都可用作 this
的参数或作为表达式的一部分。 例如,可以使用 this
重写上一示例中的第二个构造函数:
public Employee(int weeklySalary, int numberOfWeeks)
: this(weeklySalary * numberOfWeeks)
{
}
在前面的示例中使用 this
关键字会导致调用以下构造函数:
public Employee(int annualSalary) => Salary = annualSalary;
构造函数可以标记为 public
、private
、protected
、internal、protected internal 或 private protected
。 这些访问修饰符定义类的用户如何构造类。 有关详细信息,请参阅访问修饰符。
可以使用 static
关键字将构造函数声明为静态。 在访问任何静态字段之前,会自动调用静态构造函数,并用于初始化静态类成员。 有关详细信息,请参阅 静态构造函数。
C# 语言规范
有关详细信息,请参阅 C# 语言规范中的 实例构造函数 和 静态构造函数。 语言规范是 C# 语法和用法的明确来源。