Jader Dias
Jader Dias

Reputation: 90535

How to refactor these locks?

The naive solution, to move the lock to the Parent class, has a different behaviour: I will not be able to call new Child1().Method1() and new Child2().Method1() simultaneously.

Is there any way to refactor the code below?

abstract class Parent
{
    protected abstract Method1();
}

class Child1 : Parent
{
    static object staticLock = new object();

    public void Method1()
    {
        lock(staticLock)
        {
          // Do something ...
        }
    }
}

class Child2 : Parent
{
    static object staticLock = new object();

    public void Method1()
    {
        lock(staticLock)
        {
          // Do something else ...
        }
    }
}

I'm asking this because it's not only 2 child classes, so the real problem is bigger.

Upvotes: 3

Views: 145

Answers (2)

Jader Dias
Jader Dias

Reputation: 90535

Maybe this works

abstract class Parent
{
    protected abstract object StaticLock { get; }

    public void Method()
    {
        lock(staticLock)
        {
            MethodImpl();
        }
    }

    protected abstract MethodImpl();
}

class Child1 : Parent
{
    private static object staticLock = new object();

    protected override object StaticLock { get { return staticLock; } }

    protected override MethodImpl()
    {
          // Do something ...
    }
}

class Child2 : Parent
{
    private static object staticLock = new object();

    protected override object StaticLock { get { return staticLock; } }

    protected override MethodImpl()
    {
          // Do something else ...
    }
}

Upvotes: 0

Alexei Levenkov
Alexei Levenkov

Reputation: 100545

Have a method implemented by each child class that provides lock policy and move Method1 to base class as in your other question.

class Parent
{
  public void Method1()
  {
    using(acquireLock())
    {
      Method1Impl();
    }
  }
  protected abstract IDisposable acquireLock();
  protected abstract void Method1Impl();
}
class Child : Parent
{
   protected override IDisposable acquireLock()
   {
      // return some class that does appropriate locking 
      // and in Dispose releases the lock.
      // may even be no-op locking.
   }
}

Upvotes: 2

Related Questions