Reputation: 29311
I have a class which looks like:
public class WidgetDao : AbstractDao<Widget>, IWidgetDao
{
public WidgetDao(ISession session)
: base (session)
{
}
}
My code has build errors if I attempt to remove this constructor on code which looks like:
public IWidgetDao GetWidgetDao()
{
return _widgetDao ?? (_widgetDao = new WidgetDao(_session));
}
I sort of understand the reason why I get a build error... there's no explicit WidgetDao
constructor which takes one parameter. However, WidgetDao
inherits from AbstractDao<Widget>
which does have a constructor which takes one parameter.
I don't understand why the C# compiler would make an explicit constructor required on WidgetDao
when all it's used for is pass-through of the parameter to a base class.
Could someone shed some light on this for me?
Upvotes: 2
Views: 1410
Reputation: 11463
Unfortunately there is no way to automate this. The only implicit constructor that C# will give your object is the default parameterless constructor, and it only does that if there are no alternatives in your code. I'll build on this in a moment, but just for the foundation information...
Implicit MyClass()
constructor:
public class MyClass
{
}
In the above case, the compiler assumed you wanted a public parameterless constructor that didn't really do anything other than allow you to create an object. You can call new MyClass()
all day long even though you didn't create a constructor.
Now, what happens when you create your own constructor?
public class MyClass
{
public MyClass(string name)
{
Name = name;
}
public string Name { get; private set; }
}
In this case, that implicit parameterless constructor still exists, but now it's private. That means you cannot call new MyClass()
any longer and you are required to provide a name.
Now let's make our class an abstract base class:
public abstract class AbstractMyClass
{
protected AbstractMyClass(string name)
{
Name = name;
}
public string Name { get; private set; }
public abstract void DoSomething();
}
There's no way to instantiate an abstract class, so it's a best practice to make your constructors protected
. Even if you made them public
you couldn't access them directly anyway. The important thing is that the same caveat holds: the default parameterless constructor is now private. Any class that implements this base class must provide a value for name
or the class is not fully instantiated.
public class SeansClass
{
public SeansClass() : base("Sean") { }
public void DoSomething() { }
}
In this case, we re-introduced the standard parameterless constructor and had it provide the name
for our class. This is perfectly valid code. The only caveat is that the value provided in the base()
call must be a compile time constant or calculated from the parameter passed in to your class. The base()
method is always evaluated first.
There is no way for C# to make the assumption that you in fact want all implementations of a base class to have the same constructor. Each class may add constructors or provide their own values for the base class. This is merely a limitation of C#.
Upvotes: 5