【问题标题】:How to do inhereted empty constructor when Base class has constructor with parameters当基类具有带参数的构造函数时如何执行继承的空构造函数
【发布时间】:2016-05-22 17:13:18
【问题描述】:

即我有一个具有属性长度、高度、宽度和构造函数“Box(int witdth,int height,int length)”的类Box。得到一个带有属性 Name 的继承类 ProductBox。 我还有一个 .csv 文件,我用 FileHelpers 库解析到 ProductBox,所以我的构造函数是空的。 现在我不能从 Box 继承 ProductBox,因为 Box 有非空构造函数,而在 FileHelpers 中构造函数是空的。有没有办法从 Box 继承 ProductBox?

class Box
{
    int Width;
    int Height;
    int Length;

    public Box(int width, int height, int length)
    {
        this.Width = width;
        this.Height = height;
        this.Length = length;
    }
}

class ProductBox : Box
{
    string Name;
    int Width;
    int Height;
    int Length;
    public static ProductBox[] GetInfo(string filePath)
    {
        var engine = new FileHelperEngine<ProductBox>();
        var result = engine.ReadFile(filePath);
        return result;
    }
}

【问题讨论】:

    标签: c# constructor filehelpers


    【解决方案1】:

    没有。

    如果您的基类提供有参数构造函数,则不能在派生类中提供无参数构造函数,除非您将基类重新定义为也具有无参数构造函数。价值观从何而来?

    如果您的基础实际上是 struct,则可能是因为 structs 定义的默认无参数构造函数。

    您可以按照 hl3mukkel 的描述链接您的构造函数,您的派生类在其中传递构造的值。你也可以这样做:

    class ProductBox : Box
    {
        string Name;
    
        public ProductBox()
            :base(0,0,0)
        {
        }
    }
    

    如果您想自己提供默认值。

    【讨论】:

      【解决方案2】:

      从设计的角度来看,我认为你的做法是错误的。虽然您可能能够一起破解一些东西来解决您的构造函数问题,但您正在尝试将Box 类用于两种不兼容的用途。相反,您应该有两个单独的类。

      FileHelpers 是一个用于描述 csv 文件的库,以便您可以轻松地导入它们。你应该有一个BoxFileSpec 来描述你的文件。它真的不是一个合适的 C# 类——它可能有: 表示未使用列的虚拟字段;很多属性[FieldNullValue][FieldQuoted][FieldConverter];等等。它最适用于公共字段(不是 C# 最佳实践的 FileHelpers 限制)等。它是描述导入文件的 方便 语法。它应该包含任何逻辑或特殊构造函数。

      然后你可以有一个干净的最佳实践Box 类,它有你专门的构造函数和额外的逻辑、属性、方法等等。

      然后您使用FileHelperEngine&lt;BoxFileSpec&gt; 将记录读入数组并将其映射到Box 的可枚举(通过Linq 或AutoMapper 之类的库)。

      类似:

      /// A 'real' class. Add methods, getters, setters, whatever.
      /// FileHelpers doesn't use this class.
      class Box
      {
          public int Width { get; set; }
          public int Height { get; set; }
          public int Length { get; set; }
      
          public Box(int width, int height, int length)
          {
              this.Width = width;
              this.Height = height;
              this.Length = length;
          }
      }
      
      /// A 'real' class. Add methods, getters, setters, whatever.
      /// FileHelpers doesn't use this class.
      class ProductBox : Box
      {
          public ProductBox(int width, int height, int length) 
              : base(width, height, length)
          { }
      
          public int Name { get; set; }
      }
      
      /// This is the class FileHelpers will use
      /// This class describes the CSV file only. Stick to whatever
      /// syntax conventions are required by FileHelpers.
      [DelimitedRecord(";")]
      class ProductBoxFileSpec
      {
          [FieldQuoted(QuoteMode.OptionalForRead)]
          public int Width;
          [FieldQuoted(QuoteMode.OptionalForRead)]
          public int Height;
          [FieldQuoted(QuoteMode.OptionalForRead)]
          // Handle non-US formats such as , decimal points
          // convert from inches to centimetres? 
          // you get the idea...
          [FieldConverter(MyCustomizedLengthConverter)] 
          public int Length;
          [FieldOptional]
          public string SomeDummyExtraCSVColumn;
      }
      
      class Program
      {
          static void Main(string[] args)
          {
              var engine = new FileHelperEngine<ProductBoxFileSpec>();
              var productBoxRecords = engine.ReadFile(filePath);
              var productBoxes = productBoxRecords
                  .Select(x => new ProductBox(x.Width, x.Height, x.Length) { Name = x.Name });
          }
      }
      

      【讨论】:

        【解决方案3】:

        是的,如果它继承自它,你可以做构造函数链接

        public class Box 
        {
            int Width;
            int Height;
            int Length;
        
            public Box(int width, int height, int length)
            {
                this.Width = width;
                this.Height = height;
                this.Length = length;
            }
        }
        
        public class ProductBox : Box
        {
            string Name;
        
            public ProductBox(string Name, int width, int height, int length)
                : base(width, height, length)
            {
                this.Name = Name;
            }
        
            public static ProductBox[] GetInfo(string filePath)
            {
                var engine = new FileHelperEngine<ProductBox>();
                var result = engine.ReadFile(filePath);
                return result;
            }
        }
        

        【讨论】:

        • 等等。最初的问题是如何在子类中做一个无参数的构造函数。那是哪里?
        • 我无法创建带参数的 ProductBox,因为我使用的是 FileHelpers 库并且它需要一个无参数的构造函数。如果我这样做,就会出错。
        猜你喜欢
        • 1970-01-01
        • 2015-08-22
        • 2011-11-23
        • 1970-01-01
        • 2018-03-31
        • 1970-01-01
        • 2018-03-31
        • 2015-12-02
        • 2017-08-21
        相关资源
        最近更新 更多