繁体   English   中英

继承和多个构造函数

[英]Inheritance and Multiple Constructors

我有一个关于继承的问题,所以我将在下面描述这种情况:

我正在读取一个包含日志的文本文件。 (每行一个日志)每条日志行将采用以下格式:“日期类型说明”

但是,根据日志的“类型”,我将不得不以不同的方式解析“描述”并提取不同的字段。

这里有些例子:

5/1/2011 Information Field1, Field2, Field3
5/2/2011 Error       Field1

-所以,我试图做的是:
-从日志中获取一行
-根据“日期类型说明”模式进行解析
-查看“类型”字段,并根据需要创建新的对象/解析描述

public class Log
{
   public DateTime Date;
   public String Type;
   public String Description;

   public Log(String line)
   {
      this.Date = GetDate();
      this.Type = GetType();
      this.Description = GetDescription();
   }
}

public class InformationLog : Log
{
   public String Field1;
   public String Field2;
   public String Field3;

   public InformationLog(Log log)
   {
      this.Field1 = GetField1(log.Description);
      this.Field1 = GetField2(log.Description);
      this.Field1 = GetField3(log.Description);
   }
}

public class Client
{
   public void Main()
   {
       String line = ReadFileAndGetLine();  // Get a line from the file
       Log log = new Log(line);
       if(log.Type == "Information")
          log = new InformationLog(log);    // Is this right?
   }
}

这可以达到我想要的效果,但似乎这不是一个好习惯。 “ log”变量将自身用作其自己的构造函数的参数。

我的问题是:是否有标准的方法? 或者,这种实现有什么问题吗?

-
编辑:
另外,我应该提到:我的理由是我将解析该行一次以获取日期和类型,然后再次解析它以获取更详细的信息。
我决定使用继承,这样就不必解析两次“日期”和“类型”字段。

尝试使用工厂模式

static class LogFactory
{
    public static Log Create(String line)
    {
        if(GetType(line) == "Information")
           return CreateInformationLog(line);
        return CreateLog(line);
    }

    private static Log CreateLog(String line)
    {
       return new Log(line);
    }

    private static Log CreateInformationLog(String line)
    {
       return new InformationLog(line);
    }
}

然后尝试使用

   String line = ReadFileAndGetLine();  // Get a line from the file
   Log log = LogFactory.Create(line);

根据我的评论,为什么不做这样的事情:

    public enum LogEntryType
    {
        Error = -1,
        Information = 0,
    }

    public class LogEntry
    {
        public string Raw;
        public DateTime Date;
        public LogEntryType Type;
        public string Description;

        public LogEntry(String line)
        {
            Raw = line;
            Date = ParseDate();
            Type = ParseType();
            Description = ParseDescription();
        }

        public string ParseDescription()
        {
           var result = string.Empty;
           switch(Type)
           {
               case LogEntryType.Error:
                   //parse here
                   break;
               case LogEntryType.Information:
                   //parse here
                   break;
           }
           return result;
        }
    }

我注意到您在派生类中有字段,但是可以在此处解析描述。 但是,我可以理解为什么人们可能希望将其转移到实际上知道应如何解析描述的地方,在这种情况下,您可以使用其他答案中建议的工厂模式,或实施“财产袋”类型的方案-但是我认为,这些天来,人们通常会不赞成使用强力打字。

另一个建议,尽管与您最初的尝试非常相似,但倾向于封装类型的管理,而不是让一个分离的类来处理这些东西-一种模式(表面上有点像Exception ,其中您有一个根条目和内部条目:

    public enum LogEntryType
    {
        Error = -1,
        Information = 0,
    }

    public class LogEntry
    {
        public string Raw;
        public DateTime Date;
        public LogEntryType Type;
        public string Description;

        public InnerLogEntry InnerEntry;

        public LogEntry(String line)
        {
            Raw = line;
            Date = ParseDate();
            Type = ParseType();
            //parse the 'raw' description...
            Description = ParseDescription();
            //determine the inner entry type...
            switch (Type)
            {
                case LogEntryType.Error:
                    InnerEntry = new ErrorLogEntry(this);
                    break;
                case LogEntryType.Information:
                    InnerEntry = new InformationLogEntry(this);
                    break;
            }                
        }
    }

    public abstract class InnerLogEntry
    {
        protected LogEntry Parent;

        public InnerLogEntry(LogEntry logEntry)
        {
            Parent = logEntry;
        }
    }

    public class InformationLogEntry : InnerLogEntry
    {
        public InformationLogEntry(LogEntry logEntry)
            : base(logEntry)
        {
            //parse custom data
        }
    }

    public class ErrorLogEntry : InnerLogEntry
    {
        public ErrorLogEntry(LogEntry logEntry)
            : base(logEntry)
        {
            //parse custom data
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM