【问题标题】:C# Constructor - why default constructor is generated by compiler only if there is no constructor, instead of when there is no default constructorC# 构造函数 - 为什么只有在没有构造函数时才由编译器生成默认构造函数,而不是在没有默认构造函数时生成
【发布时间】:2016-10-16 11:05:26
【问题描述】:

根据 MSDN 的design guide for constructors

“如果你没有在一个类型上显式声明任何构造函数,很多语言(比如C#)会自动添加一个公共的默认构造函数。(抽象类得到受保护的构造函数。) 向类添加参数化构造函数会阻止编译器添加默认构造函数。这通常会导致意外的重大更改。”

为什么不:

“如果你没有在一个类型上显式声明任何默认构造函数,很多语言(比如C#)会自动添加一个公共的默认构造函数。(抽象类得到一个受保护的构造函数。)"

这背后的原因是什么?

【问题讨论】:

  • 请注意,术语“默认构造函数”仅适用于 C# 编译器添加的那个。如果你自己添加一个无参数构造函数,这不是默认构造函数。
  • 这与private 存在的原因相同:它消除了 API 用户的危险和不受欢迎的选项。 private 对于该语言的功能来说是绝对不必要的。它只会带走选项。

标签: c# .net constructor


【解决方案1】:

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

考虑一个旨在实现您的应用程序和磁盘上的文件之间的接口的类。必须处理构造对象而不指定要管理的文件的情况会非常不方便。

因此,由于创建非静态类的主要目的是要创建它的对象,因此您不必添加一个空的无参数构造函数如果这就是你想要的。

一旦你开始添加构造函数,那么自动魔法就会被禁用,并且不会提供默认构造函数。

【讨论】:

    【解决方案2】:

    如果我定义了一个自定义构造函数,这意味着我的对象需要以特定方式初始化,例如:

    class Customer
    {
        public Customer(string name) { this.Name = name; }
        public string Name { get; }
    }
    

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

    【讨论】:

      【解决方案3】:

      如果不存在构造函数,则无法新建类的实例。

      因此,当您提供构造函数时,至少存在一种构造类的方法。如果根本没有提供构造函数,则默认提供一个,这样你就可以真正构建类了。

      这个答案是为什么默认构造函数存在的问题,而不是当你不创建自己的无参数构造函数时它为什么不存在的问题。

      如果在您已经提供了默认构造函数的情况下提供了一个默认构造函数,这可能会导致该类的意外消耗。另一个答案中已经指出了一个例子,但就像另一个答案一样:

      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 的情况下构造该类,这不是预期行为,因此不会应用默认构造函数。

      【讨论】:

        猜你喜欢
        • 2023-03-20
        • 2016-07-18
        • 2012-06-30
        • 2016-12-16
        • 1970-01-01
        • 1970-01-01
        • 2018-03-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多