【问题标题】:Why i cannot call the default constructor while having a private constructor?为什么我不能在拥有私有构造函数时调用默认构造函数?
【发布时间】:2014-11-12 02:04:31
【问题描述】:

我有以下带有私有重载构造函数的类

 class Car
    {
        string _Make;
        string _Model;

        Car(string make, string model)
        {
            _Make = make;
            _Model = model;
        }
    }

然后我尝试调用上述类的默认构造函数

class Daytona
{
    public int Foo()
    {
        Car c = new Car(); //COMPILATION ERROR

        return 0;
    }
}

注意两个类都在同一个命名空间中!

我无法使用默认构造函数创建 Car 的实例。但是我是否创建了默认构造函数,我应该能够访问默认构造函数。但我为什么会出现这个错误?

好吧,VS 2010 发生了一些不好的事情,当我重新启动我的机器时,VS 2010 编译了上面的代码。这样问题就解决了。

它是我的编译器,当我重新编译它时,再次带来了错误,在" Car c = new Car();" 行中,错误是 MyNamespace.Car.Car(string, string) is inaccessible due to its protection level p>

但是我想把这个顶部拖到一个新区域,为什么有人要创建一个私有构造函数? (以上代码仅供测试!)

【问题讨论】:

  • 你很少需要 private 构造函数(单例就是这样)仔细考虑你使用的是什么!
  • 当您想强制所有调用者使用公共缓存或对象池时,私有构造函数也相当常见。静态工厂方法而不是构造函数允许类作者控制何时创建实例。

标签: c#


【解决方案1】:
public class Car
    {
        string _Make;
        string _Model;

        public Car(){}    

        public Car(string make, string model)
        {
            _Make = make;
            _Model = model;
        }
    }

改为public,但如果你想在没有参数的情况下调用它,你还需要添加一个无参数的构造函数。如果定义另一个构造函数(带参数),则不再隐式定义默认构造函数

【讨论】:

    【解决方案2】:

    您没有 class Carpublic 构造函数,它不需要传递参数。因此,您需要添加此构造函数。当您已经定义了另一个构造函数时,必须显式定义此构造函数。我还在你已有的构造函数中添加了public

    public class Car
    {
        string _Make;
        string _Model;
    
        public Car()
        {
            // Default constructor - does not require arguments
        }
    
        public Car(string make, string model)
        {
            _Make = make;
            _Model = model;
        }
    }
    

    如果你愿意,第二个构造函数仍然可以是私有的,但你不能直接调用它。

    现在您可以执行以下任一操作:

    Car A = new Car(); // Creates a new instance, does not set anything
    Car B = new Car("MyMake", "MyModel"); // Creates a new instance, sets make and model
    

    【讨论】:

      【解决方案3】:

      为什么要使用私有或受保护(对于子类)构造函数?工厂是完美的例子,如果您想为可能具有复杂设置等的类提供易于使用的创建工厂,那么拥有私有构造函数会阻止某人在不提供足够值的情况下创建实例:

      例子:

      public class Car
      {
      
         public static Car CreateNew()
         {
            Car c = new Car();
            c.Engine = Engine.CreateNew(4);  // 4 cyl
            //set properties so that the object will behave correctly...
            return c;
         }
         public static Car CreateNew(string make, string model, Engine e)
         {
           Car c = new Car(make,model);
           c.Engine = e;
         }
         private Car(){
         }
      
         private Car( string make, string model) : this() {
            Make = make;
            Model = model;
         }
         public string Make { get; set; }
         public string Model {get; set; }
      
         public Engine {get; private set; }
      
         //other properties that maybe are not so simple or understood
         //or properties that need to be set to control other behaviors..
      
      }
      

      现在我已经创建了工厂来创建Car,这些工厂方法是创建类实例的唯一方法。

      【讨论】:

        猜你喜欢
        • 2019-10-16
        • 2020-05-31
        • 2023-03-20
        • 2016-10-16
        • 1970-01-01
        相关资源
        最近更新 更多