使用构造函数 (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;

构造函数可以标记为 publicprivateprotectedinternalprotected internalprivate protected。 这些访问修饰符定义类的用户如何构造类。 有关详细信息,请参阅访问修饰符

可以使用 static 关键字将构造函数声明为静态。 在访问任何静态字段之前,会自动调用静态构造函数,并用于初始化静态类成员。 有关详细信息,请参阅 静态构造函数

C# 语言规范

有关详细信息,请参阅 C# 语言规范中的 实例构造函数静态构造函数。 语言规范是 C# 语法和用法的明确来源。

另请参阅