如何在每个班级和子类中最好地应用干燥的哲学并将标题设置为单个构造函数



这是一些示例代码(MWE):

public abstract class Employee
{
    protected string title = "Employee";  // underlying field
    public string Title { get { return title; } }  // read-only property
    public string Name { get; set; }  // another property
    public Employee() {}  // default ctor
    public Employee(string name) { Name = name; }  // ctor
    // how to use this in all subclasses without having to call in every ctor?
    protected Employee(string title) { this.title = title; }  // note this is protected ctor to prevent changes by users
    public virtual void Display()
    {
        Console.WriteLine("Title: {0}", Title);
    }
}

public class Associate : Employee
{
    // Properties
    public int NumberOfEngagements { get; set; }
    public Associate() : base("Associate")  // sets title as desired
    {
        NumberOfEngagements = 0;
    }
    public Associate(string name, int num_engagements)
        :base(name)
    {
        NumberOfEngagements = num_engagements;
    }
}

public class Director : Employee
{
    public int NumberOfProjectsManaged { get; set; }  // additional property
    public Director() : base("Director") { NumberOfProjectsManaged = 0; } // constructor
    public Director(string name, int num_projects)
        :base(name)
    {
        NumberOfProjectsManaged = num_projects;
    }
    public override void Display()
    {
        base.Display();
        Console.WriteLine("Number of Projects Managed: {0}", NumberOfProjectsManaged);
    }
}

public class Partner : Director
{
    // there are more than two in the actual code, but this is a MWE
    public enum SpecificTitle
    {
      Principal,
      Partner
    };
    public Partner() : base() 
    {
        this._setTitle(SpecificTitle.Partner);  // defaults to Partner
    }
    public Partner(SpecificTitle jobTitle) 
    {
        this._setTitle(jobTitle);  // overloaded ctor allows user to specify
    }
    private void _setTitle(SpecificTitle jobTitle)
    {
        switch (jobTitle)
        {
            case SpecificTitle.Principal:
                this.title = "Principal";
                break;
            case SpecificTitle.Partner:
            default:
                this.title = "Partner";
                break;
        }
    }
}

我如何在不必在每个构造函数中执行此类名称(在合作伙伴中除外)的标题?

在原始代码Title中具有以下有趣属性:

  • 它是只读的(没有setter)
  • 在构造函数中分配了一次
  • 属性的价值在大多数情况下等于类名称

考虑到,可以通过返回当前类类型名称即时计算Title的值。它被声明为虚拟,因此Partner类可以通过覆盖属性 getter

来改变默认行为
public abstract class Employee
{
    public virtual string Title 
    { 
        get { return GetType().Name; }
     }
}
public class Partner : Director {
{
      public Partner()  
      {
         this._jobTitle = SpecificTitle.Partner;  // defaults to Partner
      } 
       public Partner(SpecificTitle jobTitle) 
       {
          this._jobTitle = jobTitle;  // overloaded ctor allows user to specify
       }

     public override string Title { get {return GetJobTitle();}  

      public enum SpecificTitle
      {
          Principal,
          Partner
      };
       private SpecificTitle _jobTitle;

      private string GetJobTitle()
      {
          switch (_jobTitle)
           {
             case SpecificTitle.Principal:
               return "Principal";
             case SpecificTitle.Partner:
             default:
               return  "Partner";
            }
        }
    }

}

剩余的类声明:

public class Associate : Employee
{
   // Properties
   public int NumberOfEngagements { get; set; }
   public Associate() 
   {
      NumberOfEngagements = 0;
   }
    public Associate(int num_engagements)
    {
       this.NumberOfEngagements = num_engagements;
    }
}
public class Director : Employee
{  
   public int NumberOfProjectsManaged { get; set; }  // additional property
   public Director() : { NumberOfProjectsManaged = 0; } // constructor
   public Director(int num_projects)
   {
       NumberOfProjectsManaged = num_projects;
   }
   public override void Display()
   {
       base.Display();
       Console.WriteLine("Number of Projects Managed: {0}", NumberOfProjectsManaged);
   }
}