Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.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,我有一个包含静态对象的类:obj和一个抽象方法:AbsFoo; 继承者需要实现AbsFoo,但我还想在实现之前对obj强制一个锁,当然,在实现之后释放锁 如何实现这一点?您需要使用模板方法模式: public void AbsFoo(){ lock(obj){ doActualWork(); } } protected abstract void DoActualWork(); 简言之,您不允许实现者重写AbsFoo,而是让一个方法在初始化代码之后(在本例中为锁定)委

我有一个包含静态对象的类:obj和一个抽象方法:AbsFoo; 继承者需要实现AbsFoo,但我还想在实现之前对obj强制一个锁,当然,在实现之后释放锁


如何实现这一点?

您需要使用模板方法模式:

public void AbsFoo(){
   lock(obj){
      doActualWork();
   }
}

protected abstract void DoActualWork();

简言之,您不允许实现者重写AbsFoo,而是让一个方法在初始化代码之后(在本例中为锁定)委托给它。

您需要使用模板方法模式:

public void AbsFoo(){
   lock(obj){
      doActualWork();
   }
}

protected abstract void DoActualWork();

简而言之,您不允许实现者重写AbsFoo,而是在初始化代码之后委托给锁定的方法。

我认为您应该扩展您的设计:

在基类中准备受保护的抽象方法:AbsFooImpl和AbsFoo,如下所示:

object AbsFoo()
{
    lock(obj)
    {
        AbsFooImpl();
    }
}

我认为你应该扩展你的设计:

在基类中准备受保护的抽象方法:AbsFooImpl和AbsFoo,如下所示:

object AbsFoo()
{
    lock(obj)
    {
        AbsFooImpl();
    }
}

唯一的方法是在基类中运行代码

您将创建一个由用户调用的公共方法。此方法执行始终需要执行的代码,然后调用执行实际工作并在派生类中重写的受保护方法:

public class Foo
{
    private readonly object _syncRoot = new object();

    public void AbsFoo()
    {
        // You can do more here, like some logging
        lock(_syncRoot)
        {
            AbsInternal();
        }
    }

    protected abstract void AbsInternal();
}

public class Bar : Foo
{
    protected override void AbsInternal()
    {
        // do work.
        // Note: No call to base.AbsInternal(); or base.AbsFoo(); here
    }
}

唯一的方法是在基类中运行代码

您将创建一个由用户调用的公共方法。此方法执行始终需要执行的代码,然后调用执行实际工作并在派生类中重写的受保护方法:

public class Foo
{
    private readonly object _syncRoot = new object();

    public void AbsFoo()
    {
        // You can do more here, like some logging
        lock(_syncRoot)
        {
            AbsInternal();
        }
    }

    protected abstract void AbsInternal();
}

public class Bar : Foo
{
    protected override void AbsInternal()
    {
        // do work.
        // Note: No call to base.AbsInternal(); or base.AbsFoo(); here
    }
}
这是如何做到的:

别忘了用密封的

这是如何做到的:


别忘了用密封的

没有办法做到这一点。没有办法做到这一点。你已经更快了:我也会这么做。但在这种情况下,实现者可以直接调用DoActualWork,他可能甚至不知道DoActualWork的存在AbsFoo@choppy:实现者不必调用任何东西。请看一个更完整的例子。@Daniel Hilgarth:我的意思是,在实现者实现了DoActualWork抽象方法后,无论何时他想使用该方法或其他任何人使用该度量表,他都可能会使用instance.DoActualWork而不是base.AbsFoo,我遗漏了什么吗?@choppy:其他人都不能使用它,因为它是受保护的。课堂本身:嗯,是的,你是对的。这里的所有答案——包括我的答案——都是从外部消费者的角度来看的。对于您来说,这真的是一个场景吗,需要从派生类中调用该方法?您已经更快了:我也会这样做。但在这种情况下,实现者可以直接调用DoActualWork,他可能甚至不知道AbsFoo@choppy:实现者不必调用任何东西。请看一个更完整的例子。@Daniel Hilgarth:我的意思是,在实现者实现了DoActualWork抽象方法后,无论何时他想使用该方法或其他任何人使用该度量表,他都可能会使用instance.DoActualWork而不是base.AbsFoo,我遗漏了什么吗?@choppy:其他人都不能使用它,因为它是受保护的。课堂本身:嗯,是的,你是对的。这里的所有答案——包括我的答案——都是从外部消费者的角度来看的。这实际上是您的一个场景,需要从派生类中调用该方法吗?-1:密封在非重写方法上不仅没有用处,而且完全是非法的:无法密封,因为它不是重写的。您也不希望将AbsFoo设置为虚拟的,因为这将允许派生类绕过整个过程。为什么要密封doActualWork?-1:密封在非重写方法上不仅没有用处,而且完全是非法的:不能密封,因为它不是重写。您也不想使AbsFoo成为虚拟的,因为这将允许派生类绕过整个过程。那你为什么要做真正的工作?