多级继承可扩展方法

Multi-level Inheritance Extensible Methods

假设我有三个或更多 类:工程师:员工:人员。考虑以下示例(假设我现在使用 StringBuilder 和其他更好的做法)

public abstract class Person
{
   public string Name{get;set;}
   public string SaySomething()
   {
      string introduction = "Hello, my name is " + Name + ". ";
      return OnSaySomething(introduction);
   }
   protected virtual string OnSaySomething(string thoughts)
   { return thoughts; }
}

public abstract class Employee : Person
{
   public string Employer{get;set;}

   protected override string OnSaySomething(string thoughts)
   {
      return thoughts + "I work for " + Employer + ".";
   }
}

public class Engineer : Employee
{
   public string Discipline{get;set;}

   protected override string OnSaySomething(string thoughts)
   {
      return thoughts + "My discipline is " + Discipline + ".";
   }
}

结合上面的例子,输出为:

 Engineer engineer = new Engineer();
 engineer.Name = "Dennis Ritchie";
 engineer.Discipline = "Software Engineering";
 Console.WriteLine(engineer.SaySomething());

会产生

Hello, my name is Dennis Ritchie. My discipline is Software Engineering.

是否可以构建这些 类 以便每个覆盖 "tacks on" 更多功能,从而输出为:

Hello, my name is Dennis Ritchie. I work for . My discipline is Software Engineering.

有没有标准的方法来实现这种想法?我下意识的解决方案是在 Employee 处密封 OnSaySomething() 并引入一个新方法 OnEmployeeSaySomething()Engineer 会因为它自己的特定逻辑而覆盖它。

这似乎很快就会变得混乱,因为 SaySomething()OnSaySomething()OnEmployeeSaySomething() 都暴露在 Engineer 处(如果还有另一个级别则更糟等级制度!)。我想知道是否有更好的解决方案。感谢您的关注!

TL;DR:我想在不破坏基本逻辑的情况下进行扩展。但我不希望我的 类 真的很乱。

编辑:

有人指出了一个好的(也许是显而易见的)解决方案,这是我提供了一个错误示例的错误。相反,假设我们在这种情况下验证一些数据:

public class Level0
{
    public string Data{get;set;}
    public bool IsValid()
    {
        if (Data == null) return false;
        else return OnIsValid();
    }
    protected virtual bool OnIsValid()
    {return true;}  
}
public class Level1 : Level0
{
    public string Data_Level1{get;set;}
    protected override OnIsValid()
    {
        if (Data_level1 == null) return false;
        else return OnLevel1IsValid();
    }
    protected virtual bool OnLevel1IsValid()
    {return true;}
}
public class Level2 : Level1
{
    public string Data_Level2{get;set;}

    protected override OnLevel1IsValid()
    {
        return Data_level2 != null;
    }
}

利用基础:

protected override string OnSaySomething(string thoughts)
   {

      return base.OnSaySomething() + thoughts + "My discipline is " + Discipline + ".";
   }

我不太明白你用 "I want to extend, not override" 是什么意思,因为你显然使用了 "override" 关键字。无论如何,我可以提出以下解决方案:

public abstract class Person
{
   public string Name{get;set;}
   public virtual string SaySomething()
   {
      return = "Hello, my name is " + Name + ". ";
   }
}

public abstract class Employee : Person
{
   public string Employer{get;set;}

   public override string SaySomething()
   {
      return base.SaySomething() + "I work for " + Employer + ". ";
   }
}

public class Engineer : Employee
{
   public string Discipline{get;set;}

   public override string SaySomething()
   {
      return base.SaySomething() + "My discipline is " + Discipline + ". ";
   }
}

您需要调用该函数的基础版本,以便下一个更高级别可以构建它的字符串,然后 return 将其转换为派生版本,以便它可以添加额外的文本。

public abstract class Employee : Person
{
   public string Employer{get;set;}

   protected override string OnSaySomething(string thoughts)
   {
      return base.OnSaySomething(thoughts)+ "I work for " + Employer + ".";
   }
}

public class Engineer : Employee
{
   public string Discipline{get;set;}

   protected override string OnSaySomething(string thoughts)
   {
      return base.OnSaySomething(thoughts) + "My discipline is " + Discipline + ".";
   }
}

编辑: 使用您更新后的代码,它仍然是一回事

public class Level1 : Level0
{
    public string Data_Level1{get;set;}
    protected override bool OnIsValid()
    {
        return base.OnIsValid() && Data_level1 != null;
    }
}
public class Level2 : Level1
{
    public string Data_Level2{get;set;}

    protected override OnLevel1IsValid()
    {
        return base.OnIsValid() && Data_level2 != null;
    }
}

EDIT2:要做到这一点 "Automatic" 你几乎已经完成了实施,你可以做的另一件事是标记属性 sealed 所以在链的更下方它不能再次被覆盖,但是我不推荐这种方法,而是使用我之前示例中的覆盖。

public class Level1 : Level0
{
    public string Data_Level1 { get; set; }

    protected override sealed bool OnIsValid()
    {
        if (Data_Level1 == null) return false;
        else return OnLevel1IsValid();
    }

    protected virtual bool OnLevel1IsValid()
    {
        return true;
    }
}

public class Level2 : Level1
{
    public string Data_Level2 { get; set; }

    protected override sealed bool OnLevel1IsValid()
    {
        return Data_Level2 != null;
    }
}

需要调用基础版

protected override string OnSaySomething(string thoughts)
{
      return base.OnSaySomething(thoughts) + "My discipline is " + Discipline + ".";
}