Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以在';总是在子实现之前调用?_C#_Oop - Fatal编程技术网

C# 我可以在';总是在子实现之前调用?

C# 我可以在';总是在子实现之前调用?,c#,oop,C#,Oop,C#这里-是否可以让抽象基类定义具有默认行为的方法,并在子类实现之前调用此默认值?例如: 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 { publ

C#这里-是否可以让抽象基类定义具有默认行为的方法,并在子类实现之前调用此默认值?例如:

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
公共抽象类基类
{
公共虚拟int-GetX(int-arg)
{
如果(arg<0)返回0;
//在这里执行类似“child.GetX(arg)”的操作
}
}
公共类MyClass:Base
{
公共覆盖int GetX(int arg)
{
返回arg*2;
}
}
MyClass x=新的MyClass();
Console.WriteLine(x.GetX(5));//印刷品10
Console.WriteLine(x.GetX(-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
公共抽象类基类
{
公共覆盖int GetX(int arg)
{
如果(arg<0)返回0;
返回OnGetX(arg);
}
受保护的抽象OnGetX(int-arg);
}
公共类MyClass:Base
{
受保护的覆盖int OnGetX(int arg)
{
返回arg*2;
}
}
MyClass x=新的MyClass();
Console.WriteLine(x.GetX(5));//印刷品10
Console.WriteLine(x.GetX(-3));//打印0

模板方法模式是一条出路。根据您的需求判断,您希望基类函数始终执行一个方法。因此,您可以在基类中定义模板,例如

public void ExecuteSteps()
{
  Step1(); //Defined in base, can't be overridden.
  Step2(); //Defined as virtual in base, so sub-classes can override it
} 

请记住,这可能不是最好的解决方案:

如果允许的话,您所描述的将是“私有虚拟”功能的一个很好的使用案例;语义是派生类可以重写函数,但基版本只能从重写调用,而重写只能从基中的其他函数调用


有一种方法可以强制执行,但这有点难看。如果目标是使
X.ChainedMethod()
只能从
X.WrapperMethod()
中调用,则在X中创建一个具有
内部
构造函数的伪公共类Y,以及一个从
Y
继承并具有公共无参数构造函数的私有伪类
Z
。然后声明
X.ChainedMethod(),其中T:Z,new()
。唯一可能满足这些约束条件的类是
Y
,而
X
之外的任何类都无法访问
Y

,从某种意义上说,这有点违背了
重写
的观点,但我理解避免使用样板文件的愿望。您可以通过始终在子重写开始时调用基类的方法来简化样板。不过,除了惯例之外,我不知道还有什么办法可以强制执行。
public void ExecuteSteps()
{
  Step1(); //Defined in base, can't be overridden.
  Step2(); //Defined as virtual in base, so sub-classes can override it
}