I can't speak for him or others involved in the design of C#. However, to
me it makes perfect sense that you can't call the base constructor except
at the very beginning of the derived constructor.
<<
Maybe they should have a word with the people who designed .NET then,
because in MSIL you can apparently call the base constructor at any point
you wish
I don't recall the exact scenario, the one below was the best I could manage
to illustrate the problem. In the past I managed to work around it but I
don't recall the problem or the solution. But it was something like my
example I *think*
Whatever the problem was I managed to solve it. It's just than coming from
Delphi I was used to being able to initialise stuff before calling a base
constructor and so I got used to it. My post was to make the original
poster aware of this "pitfall".
public abstract class BaseClass
{
public BaseClass()
{
HelloMember.Value = "Hello";
GoodbyeMember.Value = "Goodbye";
}
public abstract StringMember HelloMember { get; }
public abstract StringMember GoodbyeMember { get; }
}
public class ConcreteClass : BaseClass
{
public ConcreteClass() : base
{
HelloMember = new StringMember("Hello");
GoodbyeMember = new StringMember("Goodbye");
}
public override StringMember HelloMember { get; private set; }
public override StringMember GoodbyeMember { get; private set; }
}
This will obviously throw an NullReferenceException. It's coming back to me
now I think! In C# I would have to introduce a virtual method (which is
what I did in my solution) which creates the members
public abstract class BaseClass
{
public BaseClass()
{
CreateMembers();
HelloMember.Value = "Hello";
GoodbyeMember.Value = "Goodbye";
}
protected abstract void CreateMembers();
public abstract StringMember HelloMember { get; }
public abstract StringMember GoodbyeMember { get; }
}
public class ConcreteClass : BaseClass
{
public ConcreteClass() : base
{
}
protected override void CreateMembers()
{
HelloMember = new StringMember("Hello");
GoodbyeMember = new StringMember("Goodbye");
}
public override StringMember HelloMember { get; private set; }
public override StringMember GoodbyeMember { get; private set; }
}
Whereas by being able to call the base constructor when you choose you could
do this.
public abstract class BaseClass
{
public BaseClass()
{
HelloMember.Value = "Hello";
GoodbyeMember.Value = "Goodbye";
}
public abstract StringMember HelloMember { get; }
public abstract StringMember GoodbyeMember { get; }
}
public class ConcreteClass : BaseClass
{
public ConcreteClass()
{
HelloMember = new StringMember("Hello");
GoodbyeMember = new StringMember("Goodbye");
base();
}
public override StringMember HelloMember { get; private set; }
public override StringMember GoodbyeMember { get; private set; }
}
which is less work.
Calling a constructor would allocate memory for the class's members and the
constructor merely provides a way to initialise their values. By not being
able to choose when to call the base constructor I must add an additional
virtual method just to initialise the members.
Pete