多级继承可扩展方法
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 + ".";
}
假设我有三个或更多 类:工程师:员工:人员。考虑以下示例(假设我现在使用 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 + ".";
}