Reputation: 18636
I have one base class C1
that provides a default implementation of a couple of methods as C2
and a lot of custom implementations Cx
(+20) which looks like this:
abstract class C1
{
public abstract void M1();
}
abstract class C2 : C1
{
// other overridden members ...
// M1(); has no default implementation yet.
}
class Cx : C2
{
public override void M1()
{
// ...
}
}
Now, I'd like to chain C2.M1
and Cx.M1
because I need to add a new common functionality. Usually I would create a new abstract method and call it by the second base class like this:
abstract class C1
{
public abstract void M1();
}
abstract class C2 : C1
{
// M1 should get a default implementation
// and then M1 in the next derived class should be called
public override void M1()
{
// ...
M1Internal();
}
protected abstract void M1Internal();
}
class Cx : C2
{
protected override void M1Internal()
{
// ...
}
}
However, I have over 20 such classes and updating them all is a lot of work so I was wondering if there is another way that would allow me to override M1
in both C2
and Cx
and call them in this order C1.M1()
then Cx.M1()
without creating the new intermediate helper method. Is there any better pattern for such cases?
Upvotes: 1
Views: 791
Reputation: 13488
What about simply calling base.M1
at Cx.M1
?
class Cx : C2
{
protected override void M1()
{
base.M1();//i.e. C2.M1()
//Cx.M1 internal logic
}
}
Upvotes: 1
Reputation: 5343
I think it's best to use decorator pattern in this case. Use composition rather than inheritance if possible.
abstract class C1
{
public abstract void M1();
}
class Cx : C1
{
public override void M1()
{
// ...
}
}
class CxWithCommonBehavior : C1
{
C1 realObject;
public CxWithCommonBehavior(C1 realObject)
{
this.realObject = realObject;
}
public override void M1()
{
// common behavior
realObject.M1();
}
}
Note than you need only one CxWithCommonBehavior class for all derived Cx classes - you pass the decorated instance in the constructor.
This way you can add more behaviors, chain them in all possible ways and even add or remove them at runtime
Upvotes: 3