473,501 Members | 1,702 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C# constructors annoy me!

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
22 5170
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
change class Test2 to

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

May 10 '06 #3
"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
> 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
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
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


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
> 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
"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
"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
"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
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
"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
> 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
> 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
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
> 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
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
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


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
> 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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

42
5719
by: Edward Diener | last post by:
Coming from the C++ world I can not understand the reason why copy constructors are not used in the .NET framework. A copy constructor creates an object from a copy of another object of the same...
3
1626
by: John | last post by:
Before anything else, thanks Marina, Workgroups and Ralf, for your help so far. I am now able to better define the question! After adding more console printout lines to CSum, I tried all...
0
7160
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7042
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7227
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
6932
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7420
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
4955
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3124
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1459
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
327
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.