C#here - 是否可以让抽象基类定义具有默认行为的方法,并在子类实现之前调用此默认值?例如:
public abstract class Base
{
public virtual int GetX(int arg)
{
if (arg < 0) return 0;
// do something here like "child.GetX(arg)"
}
}
public class MyClass : Base
{
public override int GetX(int arg)
{
return arg * 2;
}
}
MyClass x = new MyClass();
Console.WriteLine(x.GetX(5)); // prints 10
Console.WriteLine(x.GetX(-3)); // prints 0
基本上我不想在每个子实现中都放置相同的样板文件......
答案 0 :(得分:6)
可以问谁是谁。我过去处理这个问题的方法是创建两个方法,一个是基类中的公共方法,另一个是受保护的抽象方法(也许是虚拟的,没有实现)。
public abstract class Base
{
public int GetX(int arg)
{
// do boilerplate
// call protected implementation
var retVal = GetXImpl(arg);
// perhaps to more boilerplate
}
protected abstract int GetXImpl(int arg);
}
public class MyClass : Base
{
protected override int GetXImpl(int arg)
{
// do stuff
}
}
答案 1 :(得分:2)
如果您想确保始终调用类方法,请查看Template method pattern 此外,您的问题不是新问题,请查看this one
答案 2 :(得分:0)
如果我理解你,请看看可能会有所帮助 Template Method pattern
答案 3 :(得分:0)
我认为在没有显式base.GetX(...)
调用的情况下强制执行基本实现是不可能的。
我通常最终会在基类中包装类似的东西。所以在你的情况下是这样的:
public abstract class Base
{
public override int GetX(int arg)
{
if(arg < 0) return 0;
return OnGetX(arg);
}
protected abstract OnGetX(int arg);
}
public class MyClass : Base
{
protected override int OnGetX(int arg)
{
return arg * 2;
}
}
MyClass x = new MyClass();
Console.WriteLine(x.GetX(5)); // prints 10
Console.WriteLine(x.GetX(-3)); // prints 0
答案 4 :(得分:0)
模板方法模式是要走的路。根据您的要求判断,您希望基类函数始终执行方法。因此,您可以在基类中定义模板,例如
public void ExecuteSteps()
{
Step1(); //Defined in base, can't be overridden.
Step2(); //Defined as virtual in base, so sub-classes can override it
}
请注意,这可能不是最佳解决方案:http://tech.puredanger.com/2007/07/03/pattern-hate-template/
答案 5 :(得分:0)
如果允许这样的话,你所描述的将是“私人虚拟”功能的一个很好的使用案例;语义是派生类可以覆盖函数,但基本版本只能从覆盖中调用,而覆盖只能从基础中的其他函数调用。
有一种方法可以强制执行此操作,但它有点难看。如果目标是X.ChainedMethod()
仅可以在X.WrapperMethod()
内调用,则在X中创建一个具有internal
构造函数的虚拟公共类Y,以及一个私有虚拟类Z
它继承自Y
并具有公共无参数构造函数。然后声明X.ChainedMethod<T>() where T:Z, new()
。填充这些约束的唯一可能的类是Y
,X
之外的任何内容都不能访问Y
。