【问题标题】:Does not contain a constructor that takes 0 arguments不包含带 0 个参数的构造函数
【发布时间】:2012-08-21 17:15:35
【问题描述】:

我从以下代码中收到一条错误消息,指出“产品不包含采用 0 个参数的构造函数”:

public class Products
{
    string id;
    string name;
    double price;
    int soldCount;
    int stockCount;

    public Products(string id, string name, double price, 
                      int soldCount, int stockCount, double tax)
    {
        this.id = id;
        this.name = name;
        this.price = price;
        this.soldCount = soldCount;
        this.stockCount = stockCount;
    }
}

//I have got some get and set values for the code above 
//but it would have been too long to put in here

public class FoodProducts : Products
{
    public FoodProduct()
    {
        Console.WriteLine("This is food product");
    }

    public void Limit()
    {
        Console.WriteLine("This is an Attribute of a Product");
    }
}

【问题讨论】:

标签: c#-4.0 inheritance


【解决方案1】:

当您从 Products 继承时,您必须在自己的类中调用 Products 的基本构造。

你没有写:base(id, name, ....),所以 C# 假设​​你调用了默认的无参数构造函数,但它不存在。

Products 创建一个默认的无参数构造函数。

【讨论】:

    【解决方案2】:

    继承类的构造函数需要先构造基类。由于基类没有默认构造函数(采用 0 个参数)并且您没有使用现在拥有的非默认构造函数,因此这不起作用。所以要么A)向你的基类添加一个默认构造函数,在这种情况下,降级类的代码不需要更改;或者 B) 从降级类的构造函数中调用基类的非默认构造函数,在这种情况下,基类不需要更改。

    一个

    public class Products
    {
        public Products() { }
    }
    
    public class FoodProducts : Products
    {
        public FoodProducts() { }
    }
    

    B

    public class Products
    {
        public class Products(args) { }
    }
    
    public class FoodProducts : Products
    {
        public FoodProducts(args) : base(args) { }
    }
    

    其中一些在 msdn here 上解释得相当不错。

    【讨论】:

    • +1:我刚刚遇到了同样的错误:“[class] 不包含采用 0 个参数的构造函数”。问题是基类和每个子类都定义了一个构造函数。解决方法是确保每个子类都调用“:base(...)”来初始化父类。
    【解决方案3】:

    由于Products 没有接受0 个参数的构造函数,您必须为FoodProducts 创建一个构造函数,调用Products 的构造函数将所有必需的参数。

    在 C# 中,这是这样完成的:

    public class FoodProducts : Products
    {
    
        public FoodProducts(string id, string name, double price, int soldCount, int stockCount, double tax)   
        : base(id, name, price, soldCount, stockCount, tax)
        {
        }
    
        public void Limit()
        {
            Console.WriteLine("This is an Attribute of a Product");
        }
    }
    

    如果你不想将这个构造函数添加到FoodProducts,你也可以创建一个不带参数的构造函数到Products

    【讨论】:

      【解决方案4】:

      这里有几条关于 C# 的规则:

      1. 每个类都必须有一个构造函数(为了得到良好的构造)

      2. 如果您不提供构造函数,编译器会自动为您提供一个构造函数,无需更改。

        这意味着类

        class Demo{}
        

        在编译时提供一个空的构造函数,变成

        class Demo{
           public Demo(){}
        }
        

        我能做到

        Demo instance = new Demo();
        
      3. 如果您确实提供了构造函数(任何带有任何签名的构造函数),则不会生成空构造函数

        class Demo{
           public Demo(int parameter){}
        }
        
        Demo instance = new Demo(); //this code now fails
        Demo instance = new Demo(3); //this code now succeeds
        

        这似乎有点违反直觉,因为添加代码似乎会破坏现有的不相关代码,但这是 C# 团队的设计决定,我们必须接受它。

      4. 在调用派生类的构造函数时,如果不指定要调用的基类构造函数,编译器调用的是空的基类构造函数,所以

        class Derived:Base {
           public Derived(){}
        }
        

        变成

        class Derived:Base {
           public Derived() : base() {}
        }
        

      所以,为了构造你的派生类,你必须在基类上有一个无参数的构造函数。看到你是如何向 Products 添加构造函数的,而编译器并没有生成默认构造函数,你需要在代码中显式添加它,比如:

      public Products()
      {
      }
      

      或从派生的构造函数中显式调用它

      public FoodProduct()
             : base(string.Empty, string.Empty, 0, 0, 0, 0)
      {
      }
      

      【讨论】:

        【解决方案5】:

        只需添加

        public Products()
        {
        
        }
        

        在你的产品类中你不会出错

        原因: 每个类都存在一个带有 0 参数的默认构造函数。因此,无需(由程序员)显式定义/编写它,但是当您使用所需数量和类型的参数重载默认构造函数时,您必须自己(显式)定义默认构造函数以及重载的构造函数

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-14
          • 2012-01-01
          • 2013-02-17
          • 1970-01-01
          • 2012-08-13
          • 1970-01-01
          相关资源
          最近更新 更多