By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,369 Members | 1,207 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,369 IT Pros & Developers. It's quick & easy.

C# constructors annoy me!

P: n/a
Look at these two classes

public class Test

{

public readonly string Name;

public Test(string name)

{

this.Name = name;

}

}

public class Test2 : Test

{

}

What annoys me is that trying to execute the following code gives me an
error that Test2 doesn't have a constructor that takes 1 argument.

new Test2("Hello");

It's pretty obvious that I want to use the inherited constructor, so why
wont C# use it?
May 10 '06 #1
Share this Question
Share on Google+
22 Replies


P: n/a
Because constructors aren't inherited.

Peter Morris [Droopy eyes software] wrote:
Look at these two classes

public class Test

{

public readonly string Name;

public Test(string name)

{

this.Name = name;

}

}

public class Test2 : Test

{

}

What annoys me is that trying to execute the following code gives me an
error that Test2 doesn't have a constructor that takes 1 argument.

new Test2("Hello");

It's pretty obvious that I want to use the inherited constructor, so why
wont C# use it?

May 10 '06 #2

P: n/a
change class Test2 to

public class Test2 : Test
{
public Test2(stirng name)
{
base(name);
}
}

May 10 '06 #3

P: n/a
"Peter Morris [Droopy eyes software]" <pe**@droopyeyes.no.com.spam>
wrote:
It's pretty obvious that I want to use the inherited constructor, so why
wont C# use it?


Constructors aren't methods, so they don't need to conform to the LSP:
Barbara Liskov's Substitution Principle.

In Delphi, constructors are effectively methods of the metaclass, which
acts as a statically allocated factory object. It therefore makes sense
to inherit constructors, because they really are methods.

The Liskov Substitution Principle means that if you've got an instance
of a class C descended from a class B, you should be able to use an
instance of C wherever you use an instance of B. Since constructors
aren't methods, they don't need this substitutability support.

The fact that a descendant class can hide inherited constructors can
actually be seen as a feature. Subclasses are exactly that: subclasses,
more specific and less general than their base superclass. It stands to
reason that they may require more information to construct, and thus
require a constructor which takes more information.

If the constructors from the base class were inherited, then this would
break the descendant class's assumptions.

Alternatively, you can look at how things version. If you've written a
subclass C descended from your favourite component author's B class, you
may have requirements for your constructors that you've fulfilled by
overriding the base class's constructors. What if, in the next version,
B adds more constructors? It could break the assumptions of your class
C, because there would be a new way to construct it - that you didn't
have the chance to validate yourself.

-- Barry
May 10 '06 #4

P: n/a
> change class Test2 to

public class Test2 : Test
{
public Test2(stirng name)
{
base(name);
}
}


Shouldn't that be

public class Test2 : Test
{
public Test2(string name): base(name)
{
}
}

?
Hans Kesting
May 10 '06 #5

P: n/a
Hi,
"Dave" <da*******@gmail.com> wrote in message
news:11**********************@v46g2000cwv.googlegr oups.com...
change class Test2 to

public class Test2 : Test
{
public Test2(stirng name)
{
base(name);
}
}

This is wrong, it should be public Test2(string mane):base(name){}
--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
May 10 '06 #6

P: n/a
Hi,
What annoys me is that trying to execute the following code gives me an
error that Test2 doesn't have a constructor that takes 1 argument.

new Test2("Hello");

It's pretty obvious that I want to use the inherited constructor, so why
wont C# use it?


It's incorrect. A Test2 knows how to build a Test instance, the opposite is
not true. Constructors are not inherited, and IIRC it has been like this
always ( somebody correct me if I'm wrong ).
--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
May 10 '06 #7

P: n/a


Peter Morris [Droopy eyes software] wrote:
It's pretty obvious that I want to use the inherited constructor, so why
wont C# use it?


Inherited constructors would means that, in general, a specialization of
a class could be constructed with the same arguments as the super-class.
For many specializations this does not make sense.

It would be nice with another way to declare a constructor which would
invoke base() with the same arguments. Lots of other things would be
nice to have too.

The, rather simple -- if slightly verbose, solution is to simply copy
the constructor declaration and invoke base(args) yourself.

--
Helge
May 10 '06 #8

P: n/a
> In Delphi, constructors are effectively methods of the metaclass, which
acts as a statically allocated factory object. It therefore makes sense
to inherit constructors, because they really are methods.
Yes I head that ctors in delphi can actually return null :)
If the constructors from the base class were inherited, then this would
break the descendant class's assumptions.

Alternatively, you can look at how things version. If you've written a
subclass C descended from your favourite component author's B class, you
may have requirements for your constructors that you've fulfilled by
overriding the base class's constructors. What if, in the next version,
B adds more constructors? It could break the assumptions of your class
C, because there would be a new way to construct it - that you didn't
have the chance to validate yourself.


Does delphi suffer from that problem? Would the OP's program work with
delphi?
May 10 '06 #9

P: n/a
"cody" <de********@gmx.de> a écrit dans le message de news:
eN****************@TK2MSFTNGP05.phx.gbl...

| Yes I head that ctors in delphi can actually return null :)

Only if an exception occurs in the constructor.

| Does delphi suffer from that problem? Would the OP's program work with
| delphi?

Peter is an old hand at Delphi, just like me; his program would use the the
fact that all constructors in base classes are visible throughout the
hierarchy, whether they be virtual or not.

This visibility can, IMO, cause more problems than it cures. TObject is the
base class of all reference types, sort of analagous to System.Object but
without the reflection metadata but also with a ClassType() method that
returns an instance of TClass, a sort of metaclass, sort of analagous to
System.Type but with a Create() method which is effectively a constructor
for TObject.

This arrangement allows you to do some cool things without having to create
class factories :

TFruit = class
...
public
constructor Create; virtual; abstract
end;

TApple = class(TFruit)
...
public
constructor Create; override;
end;

TOrange = class(TFruit)
...
public
constructor Create; override;
end;

TFruitClass = class of TFruit;

var
fruitCreator: TFruitClass;
fruit: TFruit;
begin
fruitCreator := TApple;

fruit := fruitCreator.Create; //creates an Apple

fruitCreator := TOrange;

fruit := fruitCreator.Create; // creates an Orange

...
end;

Any pattern of constructor, parameterised or not, can be declared in the
base class as virtual and/or abstract and overridden in derived classes.

It is quite easy and feasible to create your own metaclasses in C# and have
virtual/abstract methods called Create(...) which then give the same idea,
essentially acting as class factories rather than the true metaclass found
in Delphi.

One major disadvantage of Delphi for Win32 is that the TObject Create
default constructor is public and not hideable, therefore you can always
circumvent a protected or private constructor such as you might use in a
Singleton class to ensure only one instance.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
May 10 '06 #10

P: n/a
"cody" <de********@gmx.de> wrote:
In Delphi, constructors are effectively methods of the metaclass, which
acts as a statically allocated factory object. It therefore makes sense
to inherit constructors, because they really are methods.


Yes I head that ctors in delphi can actually return null :)


The short answer is no, constructors can't return null (or nil as it's
called in Delphi).

There is a way to customize the memory allocation mechanism such that a
null pointer would be returned, in a similar way to the way you can
override operator new in C++, but it wouldn't be very useful because the
next step in the Delphi object construction sequence is to fill the
contents of the allocated memory with zeros, and that would cause an
access violation.
If the constructors from the base class were inherited, then this would
break the descendant class's assumptions.

Alternatively, you can look at how things version. If you've written a
subclass C descended from your favourite component author's B class, you
may have requirements for your constructors that you've fulfilled by
overriding the base class's constructors. What if, in the next version,
B adds more constructors? It could break the assumptions of your class
C, because there would be a new way to construct it - that you didn't
have the chance to validate yourself.


Does delphi suffer from that problem? Would the OP's program work with
delphi?


The OP's program would indeed work, and Delphi does have this problem.
On the other hand, it's more of a theoretical problem than a real
problem.

An advantage of Delphi's approach is that you can create virtual
constructors, and pass around metaclasses which will construct the
correct descendant when the constructor is called.

The main constructor for most components in Delphi is virtual, and as a
result of this design all the other constructors usually call the
virtual one to get correct overridden behaviour. This seems to lead to
less of a reliance on constructor parameters in class libraries designed
for Delphi, and more of a reliance on properties.

-- Barry
May 10 '06 #11

P: n/a
"Joanna Carter [TeamB]" <jo****@not.for.spam> wrote:
"cody" <de********@gmx.de> a écrit dans le message de news:
eN****************@TK2MSFTNGP05.phx.gbl...

| Yes I head that ctors in delphi can actually return null :)

Only if an exception occurs in the constructor.


If an exception occurs, nothing gets returned - the exception is
propagated!

Sorry, Joanna ;)

-- Barry
May 10 '06 #12

P: n/a
Helge Jensen wrote:
Inherited constructors would means that, in general, a specialization of
a class could be constructed with the same arguments as the super-class.
For many specializations this does not make sense.


Exactly.

Perhaps an example to visualize this. :)
First two classes:
public class Person {

private string name;

public Person(string name) {
this.name = name;
}

public string Name { get { return this.name; } }

}

public class Emplyee : Person {

private string title;

public Employee(string name, string title) : base(name) {
this.title = title;
}

public string Title { get { return this.title; } }

}
Now, if constructors were inherited, you could write the following code,
and it would cause a null reference exception:
Employee nisse = new Employee("Nisse Hult"); // uses Person constructor

string title = nisse.Title; // argh!
May 10 '06 #13

P: n/a
"Barry Kelly" <ba***********@gmail.com> a écrit dans le message de news:
sj********************************@4ax.com...

| If an exception occurs, nothing gets returned - the exception is
| propagated!
|
| Sorry, Joanna ;)

Ok, so it's a few months since I last used the Delphi language :-)

But the receiving reference gets set to nil... I think :-}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
May 10 '06 #14

P: n/a
> Now, if constructors were inherited, you could write the following code,
and it would cause a null reference exception:
Employee nisse = new Employee("Nisse Hult"); // uses Person constructor

string title = nisse.Title; // argh!


Ehm... Of course it doesn't cause an exception, but the title string
will be null.
May 10 '06 #15

P: n/a
> Now, if constructors were inherited, you could write the following code,
and it would cause a null reference exception:


But in your example you *are* creating a constructor. What I would like is
implicit constructors, so if I don't add an explicit one then the class
inherits them because it is obvious that no extra work is needed to
construct an instance.
May 11 '06 #16

P: n/a
But there is already a behaviour defined for that case. If you don't
specify any constructor, an empty constructor is created for you, that
calls the empty constructor in the base class:

public class B : A {
}

is the same as:

public class B : A {
public B() : base() {}
}

Peter Morris [Droopy eyes software] wrote:
Now, if constructors were inherited, you could write the following code,
and it would cause a null reference exception:


But in your example you *are* creating a constructor. What I would like is
implicit constructors, so if I don't add an explicit one then the class
inherits them because it is obvious that no extra work is needed to
construct an instance.

May 12 '06 #17

P: n/a
> But there is already a behaviour defined for that case.

Only on condition that you have no parameters. My classes all take a single
parameter.
May 17 '06 #18

P: n/a
Peter Morris [Droopy eyes software] wrote:
But there is already a behaviour defined for that case.


Only on condition that you have no parameters. My classes all take a single
parameter.


No, the behaviour is defined regardless of what constructors the base
class has. ;)

If the constructors would be inherited, that would mean that adding a
constructor to a base class would also magically add a constructor to
all the classes that inherit the base class. In most cases that would
mean that all the inheriting classes would get a constructor that
doesn't properly initialize the object.
May 17 '06 #19

P: n/a
Peter Morris [Droopy eyes software] <pe**@droopyeyes.no.com.spam>
wrote:
But there is already a behaviour defined for that case.


Only on condition that you have no parameters. My classes all take a single
parameter.


In that case, what would you expect to happen if classes inherited
constructors and someone used the parameterless contructor inherited
(directly or indirectly) from System.Object?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 17 '06 #20

P: n/a


Jon Skeet [C# MVP] wrote:
Peter Morris [Droopy eyes software] <pe**@droopyeyes.no.com.spam>
wrote:
But there is already a behaviour defined for that case.

Only on condition that you have no parameters. My classes all take a single
parameter.


In that case, what would you expect to happen if classes inherited
constructors and someone used the parameterless contructor inherited
(directly or indirectly) from System.Object?


One could propose a variance of default-construction that could be
claimed to be akin to "constructor-inheritance" and which makes a bit
more sense than the parameterless-default-constructor definition.

Instead of a parameterless constructor, a class will have
default-constructors corresponding to it's super-class' constructors,
all implemented by simply invoking base(...) with the arguments.

Notice that for classes with only a parameterless constructor this
yields the same semantics as now.

If *any* constructor is declared in a class, *no* default constructors
are generated, as it is now.

Also, defaulting to constructing the super-class using it's
parameterless constructor is somewhat error-prone. One could argue that
required explicit declaration of parent-construction would be "in the
spirit" of C#.

But all that's too late now, we're stuck with a default parameterless
constructor in C# -- but so are most other languages so it's not much of
a competitive parameter.

--
Helge
May 17 '06 #21

P: n/a
> In that case, what would you expect to happen if classes inherited
constructors and someone used the parameterless contructor inherited
(directly or indirectly) from System.Object?


That's simple. In the base class I would implement a parameterless
constructor and mark it as obsolete.
May 19 '06 #22

P: n/a
Peter Morris [Droopy eyes software] <pe**@droopyeyes.no.com.spam>
wrote:
In that case, what would you expect to happen if classes inherited
constructors and someone used the parameterless contructor inherited
(directly or indirectly) from System.Object?


That's simple. In the base class I would implement a parameterless
constructor and mark it as obsolete.


Euch - I really don't like that idea. For one thing, it means that you
have to do that for every overload you *don't* want to support for all
your base classes - and if an extra constructor is added to the base
class in a new version, you may not even notice. Do you really want to
have to check for new constructors for all your base classes all the
time?

I think it's better to say what constructors you explicitly *do* want
to support, personally.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
May 19 '06 #23

This discussion thread is closed

Replies have been disabled for this discussion.