C#构造函数 - 为什么默认构造函数只有在没有构造函数时才会被编译器生成,而不是在没有默认构造函数时生成?

5
根据 MSDN 的构造函数设计指南
“如果您在类型上没有显式声明任何构造函数,则许多语言(如 C#)将自动添加公共默认构造函数。 (抽象类获得受保护的构造函数。)向类添加参数化构造函数会防止编译器添加默认构造函数。 这通常会导致意外的破坏性变化。”
为什么不这样说:
“如果您在类型上没有显式声明任何默认构造函数,则许多语言(如 C#)将自动添加公共默认构造函数。 (抽象类获得受保护的构造函数。)”
这背后的原因是什么?

请注意,“默认构造函数”一词仅适用于C#编译器添加的构造函数。如果您自己添加了一个无参数的构造函数,则这不是默认构造函数。 - Lasse V. Karlsen
这就是为什么private存在的原因:它从API用户中消除了危险和不良选项。对于语言的功能来说,private是严格不必要的。它只是消除了一些选项。 - usr
3个回答

14

因为并非所有类都应该构造成无参数形式。

考虑一个设计用于实现应用程序和磁盘文件之间接口的类。如果必须处理未指定要管理哪个文件时构造对象的情况,那将非常不方便。

因此,如果你创建非静态类的主要目的只是为了创建其对象,则无需添加空的无参构造函数(如果这是你想要的全部)

当你开始添加任何构造函数,则自动处理功能将被禁用,不会提供默认构造函数。


6
如果我定义了一个自定义构造函数,这意味着我的对象需要以特定的方式初始化,例如:
class Customer
{
    public Customer(string name) { this.Name = name; }
    public string Name { get; }
}

如果编译器也添加了 public Customer(),那么您就可以绕过要求以名称初始化客户端的要求。

2
如果没有构造函数,就无法创建该类的实例。因此,当您提供构造函数时,至少有一种方法可以构造该类。如果根本没有提供构造函数,则会默认提供一个,以便您可以实际构建该类。
这解答了为什么存在默认构造函数的问题,但不解答为什么在您没有创建自己的无参数构造函数时不存在默认构造函数。
如果已经提供了默认构造函数,再提供一个可能会导致对该类的意外消耗。另一个答案中已经指出了这种情况的示例,这里只是再举一个例子:
public class Foo
{

    private readonly IDbConnection _dbConnection;

    public Foo(IDbConnection dbConnection)
    {
        if (dbConnection == null)
            throw new ArgumentNullException(nameof(dbConnection));

        _dbConnection = dbConnection;
    }

    public Whatever Get()
    {
        var thingyRaw = _dbConnection.GetStuff();
        var thingy = null; // pretend some transformation occurred on thingyRaw to get thingy
        return thingy;
    }

}

如果在上述类中自动创建默认构造函数,则可以在没有其依赖项IDbConnection的情况下构造该类,但这不是预期行为,因此不应用默认构造函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接