Reputation: 27335
An external framework has the following classes:
public class Boatmaker
{
}
public class Wood
{
}
public class Axe
{
}
public class Lake
{
}
public class Boat
{
public Boat(Wood wood, Axe axe) {
}
public Boat (Boatmaker maker) {
}
public Boat (Lake lake) {}
}
I need to do a lot of subclassing of Boat. For each of my subclasses, I have to assume that the external framework may want to instantiate it via any of the above constructors. So my subclasses get pass-through constructors. Notice how they never go away:
public class SmallBoat: Boat
{
public void DoSmallBoatStuff() {
// some code here
}
private void Initialize() {
this.DoSmallBoatStuff();
}
public SmallBoat(Wood wood, Axe axe): base(wood, axe) {
this.Initialize();
}
public SmallBoat (Boatmaker maker): base(maker) {
this.Initialize();
}
public SmallBoat (Lake lake): base(lake) {
this.Initialize();
}
}
public class Canoe: SmallBoat
{
public void DoCanoeStuff() {
// some code here
}
private void Initialize() {
this.DoCanoeStuff();
}
public Canoe(Wood wood, Axe axe): base(wood, axe) {
this.Initialize();
}
public Canoe (Boatmaker maker): base(maker) {
this.Initialize();
}
public Canoe(Lake lake): base(lake) {
this.Initialize();
}
}
I am wondering if there is a way to simplify the appearance of the code. The only difference between the way the constructors are written in SmallBoat and Canoe is the word SmallBoat or Canoe. Everything else is the same.
So if there were a way to write a constructor without actually using the name of the class in the constructor, it would help a lot. I could use direct copy and paste without a .tt file (which is not really viable for me -- most of my work is not done in Visual Studio). Is there a way to do that?
Upvotes: 3
Views: 535
Reputation: 10486
If you can change the design, I highly recommend separate object instantiation from the object itself. This way, the Factory Method combining with Template Method design pattern comes very helpful:
public abstract class BoatFactory
{ protected abstract void Initialize();
protected Wood Wood;
protected Axe Axe
protected Boatmaker Boatmaker ;
public Boat MakeBoat(Wood wood, Axe axe)
{
this.Wood = wood;
this.Axe = axe;
Initialize();
}
public Boat MakeBoat(Boatmaker maker)
{
this.Boatmaker = Boatmaker ;
Initialize();
}
public Boat MakeBoat(Lake lake)
{
this.Lake = lake;
Initialize();
}
}
public class SmallBoatFactory : BoatFactory
{
protected override void Initialize()
{
// do customized init operations here
}
}
Upvotes: 1
Reputation: 4913
1. Automation of code typing
There is code snippet : ctor
that helps create "only" default constructor.
To use it type ctor
an tabulation twice.
The original code snippet can be copied to create your own.
In Visual Studio, go in Tools menu/Code snippet manager
.
You can see here the directories of the snippet files.
You can copy a snippet ( ctor.snippet
for instance ) to "My Code Snippets
", rename it and edit.
2. Design of the boat hierarchy
The boat hierarchy can also be designed so there is only a default constructor in the base class, and you have public properties or public method(s) in the base class to provide Lake
, Axe
, BoatMaker
, ...
Upvotes: 1
Reputation: 157118
No. There is not. You have to specify which constructors of the base class you want to make available from the current class. There is no way to write the constructor without mentioning the real class name.
It might be a simplification you are showing, but if Initialize
is the only method called, you might want to move that call to the base class calling a protected Initialize
method you can override from the implementing classes. (You have to take in consideration the order of calling that method and instantiating properties/fields. You can run into trouble there, so it might not be viable in your situation)
Upvotes: 1