473,466 Members | 1,548 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Constructors

I have an object persistence framework I have written, this framework
expects every object to descend ultimately from PersistentObject and to have
a constructor (ObjectSpace objectSpace) so that objects may be recreated.

PersistentObject's constructor will do something like this

this.ObjectSpace = objectSpace;
objectSpace.RegisterObjectCreation(this);

The object space will record a reference to this new object + do something
like this

if (!IsLoadingFromDatabase)
newInstance.AfterConstruction();
The virtual AfterConstruction method on a class is therefore only ever
called when an object is initially created and not when it is recreated due
to being fetched from the database. This gives a good opportunity to create
composite objects etc. Here is my problem

public class CustomerAction : PersistentObject
{
public CustomerAction(Customer customer)
: base(customer.ObjectSpace)
{
this.Customer = customer;
}

protected override void AfterConstruction()
{
//Do some stuff with this.Customer
}
}

My problem is that this.Customer has not been set by the time
AfterConstruction is called.

1) new CustomerAction(someCustomer);
2) CustomerAction constructor is called
3) Base constructor (customer.ObjectSpace is called)
4) CustomerAction.AfterConstruction is called
5) CustomerAction constructor code is executed

Why oh why wont dotnet let me execute some of my own code before calling the
base constructor? I can do this in methods.

I find it so restrictive!

Jul 20 '06 #1
68 3441
Peter,
I don't mean to sound disrespectful, but I've observed that often when
people make complaints like yours it is because they have engineering flaws
in their code pattern, not because the Framework is "restrictive". Perhaps
you ought to consider refactoring your design pattern?
Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com


"Peter Morris [Droopy eyes software]" wrote:
I have an object persistence framework I have written, this framework
expects every object to descend ultimately from PersistentObject and to have
a constructor (ObjectSpace objectSpace) so that objects may be recreated.

PersistentObject's constructor will do something like this

this.ObjectSpace = objectSpace;
objectSpace.RegisterObjectCreation(this);

The object space will record a reference to this new object + do something
like this

if (!IsLoadingFromDatabase)
newInstance.AfterConstruction();
The virtual AfterConstruction method on a class is therefore only ever
called when an object is initially created and not when it is recreated due
to being fetched from the database. This gives a good opportunity to create
composite objects etc. Here is my problem

public class CustomerAction : PersistentObject
{
public CustomerAction(Customer customer)
: base(customer.ObjectSpace)
{
this.Customer = customer;
}

protected override void AfterConstruction()
{
//Do some stuff with this.Customer
}
}

My problem is that this.Customer has not been set by the time
AfterConstruction is called.

1) new CustomerAction(someCustomer);
2) CustomerAction constructor is called
3) Base constructor (customer.ObjectSpace is called)
4) CustomerAction.AfterConstruction is called
5) CustomerAction constructor code is executed

Why oh why wont dotnet let me execute some of my own code before calling the
base constructor? I can do this in methods.

I find it so restrictive!

Jul 20 '06 #2
"Peter Morris [Droopy eyes software]" <pe**@droopyeyes.no.com.spama écrit
dans le message de news: %2****************@TK2MSFTNGP02.phx.gbl...

| The virtual AfterConstruction method on a class is therefore only ever
| called when an object is initially created and not when it is recreated
due
| to being fetched from the database. This gives a good opportunity to
create
| composite objects etc. Here is my problem
|
| public class CustomerAction : PersistentObject
| {
| public CustomerAction(Customer customer)
| : base(customer.ObjectSpace)
| {
| this.Customer = customer;
| }
|
| protected override void AfterConstruction()
| {
| //Do some stuff with this.Customer
| }
| }

Then, if you are setting the Customer property from the constructor, why not
simply use the Customer property setter to do anything after the property is
set ?

| Why oh why wont dotnet let me execute some of my own code before calling
the
| base constructor? I can do this in methods.
|
| I find it so restrictive!

There is always a way around this, it just requires a change of perspective
:-)

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jul 20 '06 #3
"Why oh why wont dotnet let me execute some of my own code before calling
the base constructor? "

Oh, it's not dotnet problem. It's not a problem at all.
If you are a child (your object) of someone (your parent object), your
parent must be alive before you can be alive.
That's why it's mandatory that the parent object is constructed first before
your object.
Rethink your design.

"Peter Morris [Droopy eyes software]" <pe**@droopyeyes.no.com.spamha
scritto nel messaggio news:%2****************@TK2MSFTNGP02.phx.gbl...
>I have an object persistence framework I have written, this framework
expects every object to descend ultimately from PersistentObject and to
have a constructor (ObjectSpace objectSpace) so that objects may be
recreated.

PersistentObject's constructor will do something like this

this.ObjectSpace = objectSpace;
objectSpace.RegisterObjectCreation(this);

The object space will record a reference to this new object + do something
like this

if (!IsLoadingFromDatabase)
newInstance.AfterConstruction();
The virtual AfterConstruction method on a class is therefore only ever
called when an object is initially created and not when it is recreated
due to being fetched from the database. This gives a good opportunity to
create composite objects etc. Here is my problem

public class CustomerAction : PersistentObject
{
public CustomerAction(Customer customer)
: base(customer.ObjectSpace)
{
this.Customer = customer;
}

protected override void AfterConstruction()
{
//Do some stuff with this.Customer
}
}

My problem is that this.Customer has not been set by the time
AfterConstruction is called.

1) new CustomerAction(someCustomer);
2) CustomerAction constructor is called
3) Base constructor (customer.ObjectSpace is called)
4) CustomerAction.AfterConstruction is called
5) CustomerAction constructor code is executed

Why oh why wont dotnet let me execute some of my own code before calling
the base constructor? I can do this in methods.

I find it so restrictive!

Jul 20 '06 #4
Laura T <laura.t@_yahoo.comwrote:
"Why oh why wont dotnet let me execute some of my own code before calling
the base constructor? "
That works in C++ correctly [in my opinion], but it doesn't work in .NET. It
is very annoying to work around. I wish it were possible to put:

// constructor
public SubClass(int variable) {
// do something here
base(variable);
}
Oh, it's not dotnet problem. It's not a problem at all.
If you are a child (your object) of someone (your parent object), your
parent must be alive before you can be alive.
That's why it's mandatory that the parent object is constructed first before
your object.
Rethink your design.
I think it is inconvenient at best. You can easily do such things in C++
without issue.

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

Jul 20 '06 #5
"Peter Bromberg [C# MVP]" <pb*******@yahoo.nospammin.coma écrit dans le
message de news: 70**********************************@microsoft.com...

| I don't mean to sound disrespectful, but I've observed that often when
| people make complaints like yours it is because they have engineering
flaws
| in their code pattern, not because the Framework is "restrictive".
Perhaps
| you ought to consider refactoring your design pattern?

I'm sorry Peter, but I know Pete Morris' work and it is not flaws in his
engineering pracices.

Peter, like I, comes from a Delphi background; a language which allows code
before the call to the inherited constructor.

When you have used a language like Delphi or C++ that allows this practice,
then you tend to design towards the capabilities of those languages. Moving
to a different language that has different features does take some getting
used to and I guess that P.M. will have to refactor, just as I have.

However, moving existing design patterns to a different language is not a
trivial task, but it is definitely *not* because of design failures.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jul 20 '06 #6
"Laura T" <laura.t@_yahoo.coma écrit dans le message de news:
Ok**************@TK2MSFTNGP02.phx.gbl...

| Oh, it's not dotnet problem. It's not a problem at all.
| If you are a child (your object) of someone (your parent object), your
| parent must be alive before you can be alive.
| That's why it's mandatory that the parent object is constructed first
before
| your object.
| Rethink your design.

This is almost arrogant and doesn't consider the fact that Peter is a
skilled programmer and is making the transition from Delphi, C#'s parent;
which does allow code before inherited constructor calls.

That's why you have to consider that if it weren't for Delphi, you wouldn't
be using C# :-)

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jul 20 '06 #7
Joanna Carter [TeamB] <jo****@not.for.spamwrote:
>
This is almost arrogant and doesn't consider the fact that Peter is a
skilled programmer and is making the transition from Delphi, C#'s parent;
which does allow code before inherited constructor calls.
If anything, C++ is C#'s parent. In reality, I think Java is <duck!!!>.
That's why you have to consider that if it weren't for Delphi, you wouldn't
be using C# :-)
Yahoo ... Pascal was late in the OO game ... and Borland did it with Turbo
Pascal (I used to love programming in TurboVision when the whole world was DOS
and DPMI).

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

Jul 20 '06 #8
"Thomas T. Veldhouse" <ve*****@yahoo.coma écrit dans le message de news:
FI******************************@giganews.com...

| If anything, C++ is C#'s parent. In reality, I think Java is <duck!!!>.

<g>

My allusion is to the fact that Anders Heijlsberg (sp?) was architect on
Delphi before doing the same for C# :-)

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jul 20 '06 #9
Joanna Carter [TeamB] <jo****@not.for.spamwrote:
"Thomas T. Veldhouse" <ve*****@yahoo.coma ?crit dans le message de news:
FI******************************@giganews.com...

| If anything, C++ is C#'s parent. In reality, I think Java is <duck!!!>.

<g>

My allusion is to the fact that Anders Heijlsberg (sp?) was architect on
Delphi before doing the same for C# :-)
Gotcha ... I didn't know that. Good old Microsoft ate up its little cousin
;-)

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

Jul 20 '06 #10
Oh, it's not dotnet problem. It's not a problem at all.
If you are a child (your object) of someone (your parent object), your
parent must be alive before you can be alive.
I don't think that is quite right. I believe that the object instance
exists immediately, all constructors actually do is to initialise the
members of the instance. So why can't I explicitly specify the order in
which initialisation occurs as I can with virtual methods?

Jul 20 '06 #11
Then, if you are setting the Customer property from the constructor, why
not
simply use the Customer property setter to do anything after the property
is
set ?
Because the value should effectively be readonly. In such a case I'd like
to ensure that the code will not compile unless I pass a customer.

But there are other considerations too, for example

public Class1
{
public Class1(Customer customer)
{
this.Customer = Customer;
do some stuff with customer, create some child objects etc
}
}
public SpecialClass1 : Class1
{
public SpecialClass1(Customer customer) : base(customer)
{
//this class is special so needs some special checks first
if (!DoSpecialChecks(customer))
throw new SomeExceptionType("The special checks failed");
}
}

Why should I go through potentially lots of base constructors + create all
the child objects etc (which may be expensive to create in terms of
resources) only to eventually be denied the possibility of creating the
object instance? It would be much better as this

public SpecialClass1 : Class1
{
public SpecialClass1(Customer customer)
{
//this class is special so needs some special checks first
if (!DoSpecialChecks(customer))
throw new SomeExceptionType("The special checks failed");

base(customer);
}
}
Or what if the parent constructor expects an ObjectSpace?

public ChildClass : PersistentObject
{
public ChildClass(Customer customer)
{
if (customer == null)
throw new ArgumentNullException("ChildClass constructor - customer");
if (customer.ObjectSpace == null)
throw new ArgumentException("ChildClass constructor - customer has no
object space");

base(customer.ObjectSpace);
}
}

So instead of my nicely formatted + (more importantly) expected exception
types I get a NullReferenceException because I can't write the code exactly
how I just did, the base constructor is called before my code gets a chance
to execute.

There are lots of reasons why someone might want to initialise code before
the base constructor code executes, I find it quite restrictive that I
cannot do it.

Pete
Jul 20 '06 #12
"Peter Morris [Droopy eyes software]" <pe**@droopyeyes.no.com.spama écrit
dans le message de news: uI**************@TK2MSFTNGP03.phx.gbl...

| I don't think that is quite right. I believe that the object instance
| exists immediately, all constructors actually do is to initialise the
| members of the instance.

Not in .NET; even Delphi for .NET doesn't allow anything before the
inherited constructor.

..NET constructors really do create the object and until you have reached the
constructor in the root class of a hierarchy, the object does not yet exist.
That seems to be the model that .NET follows.

| So why can't I explicitly specify the order in
| which initialisation occurs as I can with virtual methods?

Because C# doesn't support virtual static methods and constructors are a
special case static method ?

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jul 20 '06 #13
"Thomas T. Veldhouse" <ve*****@yahoo.coma écrit dans le message de news:
NJ******************************@giganews.com...

| Gotcha ... I didn't know that. Good old Microsoft ate up its little
cousin
| ;-)

Whoa!! Delphi is still very much alive and well. What is more it is one of
the few languages that can provide a single code base that will compile to
both Win32 *and* .NET.

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jul 20 '06 #14
"Peter Morris [Droopy eyes software]" <pe**@droopyeyes.no.com.spama écrit
dans le message de news: Oj**************@TK2MSFTNGP05.phx.gbl...

| Because the value should effectively be readonly. In such a case I'd like
| to ensure that the code will not compile unless I pass a customer.

Then you can have a split-visibility property where the setter is less
visible than the getter

public Customer Customer
{
get { return customer; }
private set
{
// other stuff
customer = value;
}

| But there are other considerations too, for example
|
| public Class1
| {
| public Class1(Customer customer)
| {
| this.Customer = Customer;
| do some stuff with customer, create some child objects etc
| }
| }

| Or what if the parent constructor expects an ObjectSpace?
|
| public ChildClass : PersistentObject
| {
| public ChildClass(Customer customer)
| {
| if (customer == null)
| throw new ArgumentNullException("ChildClass constructor - customer");
| if (customer.ObjectSpace == null)
| throw new ArgumentException("ChildClass constructor - customer has no
| object space");
|
| base(customer.ObjectSpace);
| }
| }

Aaah! in this case, you can use a private static method to do the checks,
etc on the incoming parameter, something like this :

class CustomerAction
{
private Customer customer;

private static Customer DoSomething(Customer customer)
{
return customer;
}

private CustomerAction(Customer customer, object dummy) : base()
{
this.customer = customer;
}

public CustomerAction(Customer customer) : this(DoSomething(customer),
null) { }
}

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jul 20 '06 #15
Joanna Carter [TeamB] <jo****@not.for.spamwrote:
| I don't think that is quite right. I believe that the object instance
| exists immediately, all constructors actually do is to initialise the
| members of the instance.

Not in .NET; even Delphi for .NET doesn't allow anything before the
inherited constructor.

.NET constructors really do create the object and until you have reached the
constructor in the root class of a hierarchy, the object does not yet exist.
That seems to be the model that .NET follows.
Nope. Otherwise virtual method calls being made from the constructor
couldn't run the overridden implementation in the derived class, which
they do.

In fact, C# *does* run code before the base class constructor - it
executes the variable initialisers. (Note that this is different from
Java, which doesn't even execute the variable initializers before
running the superclass constructor.)

Here's an example to prove my point:

using System;

class Base
{
internal Base()
{
Console.WriteLine ("Base constructor");
}
}

class Derived : Base
{
int x = MakeSomeCall();

public Derived()
{
}

static int MakeSomeCall()
{
Console.WriteLine ("Called from variable initializer");
return 0;
}

static void Main()
{
new Derived();
}
}

Look at the code in ildasm or reflector - the call to MakeSomeCall is
genuinely before the call to the base constructor.

I suspect the reason for disallowing arbitrary placement of base
constructor calls is because an object can't guarantee to operate
properly before its parent parts are properly initialised. Of course,
if you make calls to virtual methods in the constructor, you can end up
calling into a derived class before *that's* had a chance to fully
initialize, too - which is a reason not to do that.

However, it's more common to want to access things to do with your
parent than it is to want to call overridden methods in a constructor.

I usually find there are ways round this when I really want to do
something before the constructor code is executed.

--
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
Jul 20 '06 #16
Peter Morris [Droopy eyes software] <pe**@droopyeyes.no.com.spam>
wrote:
Because the value should effectively be readonly. In such a case I'd like
to ensure that the code will not compile unless I pass a customer.

But there are other considerations too, for example

public Class1
{
public Class1(Customer customer)
{
this.Customer = Customer;
do some stuff with customer, create some child objects etc
}
}
public SpecialClass1 : Class1
{
public SpecialClass1(Customer customer) : base(customer)
{
//this class is special so needs some special checks first
if (!DoSpecialChecks(customer))
throw new SomeExceptionType("The special checks failed");
}
}
In this case I'd create a static method which returns a SpecialClass1,
and make the constructor private.

<snip>
Or what if the parent constructor expects an ObjectSpace?

public ChildClass : PersistentObject
{
public ChildClass(Customer customer)
{
if (customer == null)
throw new ArgumentNullException("ChildClass constructor - customer");
if (customer.ObjectSpace == null)
throw new ArgumentException("ChildClass constructor - customer has no
object space");

base(customer.ObjectSpace);
}
}
In this case I'd write a static method which does the check, and call
that:

public ChildClass (Customer customer)
: base (RetrieveObjectSpace(customer))
{
...
}

static ObjectSpace RetrieveObjectSpace (Customer customer)
{
// Same checks as you would have had in the constructor
}

I'm not trying to defend the decision (I'm ambivalent about it) - just
giving you some workarounds.

--
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
Jul 20 '06 #17
Joanna Carter [TeamB] <jo****@not.for.spamwrote:

<snip>
Aaah! in this case, you can use a private static method to do the checks,
etc on the incoming parameter, something like this :

class CustomerAction
{
private Customer customer;

private static Customer DoSomething(Customer customer)
{
return customer;
}

private CustomerAction(Customer customer, object dummy) : base()
{
this.customer = customer;
}

public CustomerAction(Customer customer) : this(DoSomething(customer),
null) { }
}
Actually, in this case the parent constructor expects a parameter, so
there's no need for the extra constructor - just the extra method.

However, the idea of putting in a dummy constructor is nice. Well, no,
not nice - horribly evil - but effective. Mmm...

--
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
Jul 20 '06 #18
"Joanna Carter [TeamB]" <jo****@not.for.spamwrote in message
news:um**************@TK2MSFTNGP02.phx.gbl...
>
Peter, like I, comes from a Delphi background; a language which allows
code
before the call to the inherited constructor.

When you have used a language like Delphi or C++ that allows this
practice,
This capability is not available in C++, IIRC.

///ark
Jul 20 '06 #19
"Jon Skeet [C# MVP]" <sk***@pobox.coma écrit dans le message de news:
MP************************@msnews.microsoft.com...

| Nope. Otherwise virtual method calls being made from the constructor
| couldn't run the overridden implementation in the derived class, which
| they do.

Huh ? You lost me there.

| In fact, C# *does* run code before the base class constructor - it
| executes the variable initialisers. (Note that this is different from
| Java, which doesn't even execute the variable initializers before
| running the superclass constructor.)

Picky ! :-)

| I usually find there are ways round this when I really want to do
| something before the constructor code is executed.

Like... ?

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jul 20 '06 #20
Joanna Carter [TeamB] <jo****@not.for.spamwrote:
| Nope. Otherwise virtual method calls being made from the constructor
| couldn't run the overridden implementation in the derived class, which
| they do.

Huh ? You lost me there.
Actually, having reread your statement, mine indeed doesn't follow.
However, the fact that variables can be set before the base class
constructor is executed shows that to some extent at least, the object
*does* exist - the memory must have been allocated, at least, otherwise
those variables wouldn't exist.
| In fact, C# *does* run code before the base class constructor - it
| executes the variable initialisers. (Note that this is different from
| Java, which doesn't even execute the variable initializers before
| running the superclass constructor.)

Picky ! :-)

| I usually find there are ways round this when I really want to do
| something before the constructor code is executed.

Like... ?
Like the ways we've already shown, executing static methods etc.

--
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
Jul 21 '06 #21
Hi Jon
In this case I'd create a static method which returns a SpecialClass1,
and make the constructor private.
I have this code pattern in my objects too, for example.

SomeClass.ForSiteVisit(SiteVisit)
SomeClass.ForPlannedVisit(PlannedVisit);
SomeClass.ForCustomer(Customer);

I can work out the customer from SiteVisit and PlannedVisit (because in both
cases you are visiting a customer), but this means that I end up
copy/pasting code into each *or* having a static method.

I don't actually have a problem I need to work around, I just find it
annoying that I can't specify at which point I want my base constructor code
called, it's a bit rubbish to be quite blunt about it :-)

Pete
Jul 21 '06 #22
Actually, having reread your statement, mine indeed doesn't follow.
However, the fact that variables can be set before the base class
constructor is executed shows that to some extent at least, the object
*does* exist - the memory must have been allocated, at least, otherwise
those variables wouldn't exist.
Yes, a good point! So the object *does* exist before the base is called,
and the constructors are merely initialisation code?

Like the ways we've already shown, executing static methods etc.
They reek too much of "workaround" though don't you think? I think you
should look at code and see the purpose, not look at it and have to try to
understand why it looks so weird.

this.Customer = customer
base(Customer.ObjectSpace);

Perfectly simple!
Pete

Jul 21 '06 #23
"Jon Skeet [C# MVP]" <sk***@pobox.coma écrit dans le message de news:
MP************************@msnews.microsoft.com...

| Actually, having reread your statement, mine indeed doesn't follow.
| However, the fact that variables can be set before the base class
| constructor is executed shows that to some extent at least, the object
| *does* exist - the memory must have been allocated, at least, otherwise
| those variables wouldn't exist.

What!! You mean we have to admit that Peter was right ? :-))

| Like the ways we've already shown, executing static methods etc.

Also coming from a Delphi background, I sort of agree with Peter that it
should be possible to have code before the inherited constructor call but,
heyho, times change. After all, I had to do some odd OO things to cope with
some Delphi features, so why not expect similar with C# ? :-)

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer
Jul 21 '06 #24
Mark Wilden wrote:
"Joanna Carter [TeamB]" <jo****@not.for.spamwrote in message
news:um**************@TK2MSFTNGP02.phx.gbl...
>Peter, like I, comes from a Delphi background; a language which allows
code
before the call to the inherited constructor.

When you have used a language like Delphi or C++ that allows this
practice,

This capability is not available in C++, IIRC.
....

I would say so also. Overriden virtual member function in derived class
should not be called at all. It should call the base version. Which kind
of makes sense, because derived object is not constructed yet.

Regards,
Goran
Jul 21 '06 #25
Joanna Carter [TeamB] <jo****@not.for.spamwrote:
"Thomas T. Veldhouse" <ve*****@yahoo.coma ?crit dans le message de news:
NJ******************************@giganews.com...

| Gotcha ... I didn't know that. Good old Microsoft ate up its little
cousin
| ;-)

Whoa!! Delphi is still very much alive and well. What is more it is one of
the few languages that can provide a single code base that will compile to
both Win32 *and* .NET.
I like C++ on Qt ... it will compile to Win32, Linux (multilib), FreeBSD,
Soloaris ... etc ;-)

But ... my clients like it when I offer .NET solutions, so I give them what
they want. :-)

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

Jul 21 '06 #26
Jon Skeet [C# MVP] <sk***@pobox.comwrote:
Joanna Carter [TeamB] <jo****@not.for.spamwrote:
>| Nope. Otherwise virtual method calls being made from the constructor
| couldn't run the overridden implementation in the derived class, which
| they do.

Huh ? You lost me there.

Actually, having reread your statement, mine indeed doesn't follow.
However, the fact that variables can be set before the base class
constructor is executed shows that to some extent at least, the object
*does* exist - the memory must have been allocated, at least, otherwise
those variables wouldn't exist.
>| In fact, C# *does* run code before the base class constructor - it
| executes the variable initialisers. (Note that this is different from
| Java, which doesn't even execute the variable initializers before
| running the superclass constructor.)

Picky ! :-)

| I usually find there are ways round this when I really want to do
| something before the constructor code is executed.

Like... ?

Like the ways we've already shown, executing static methods etc.
Static methods do not get around the problem, because they can not be virtual
[if they could, by definition, they could not be static].

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

Jul 21 '06 #27
What!! You mean we have to admit that Peter was right ? :-))>

/me polishes knuckles :-)
Also coming from a Delphi background, I sort of agree with Peter that it
should be possible to have code before the inherited constructor call but,
heyho, times change. After all, I had to do some odd OO things to cope
with
some Delphi features, so why not expect similar with C# ? :-)

Joanna

--
Joanna Carter [TeamB]
Consultant Software Engineer


Jul 21 '06 #28

"Goran Sliskovic" <gs******@yahoo.comwrote in message
news:OC**************@TK2MSFTNGP04.phx.gbl...
Mark Wilden wrote:
>"Joanna Carter [TeamB]" <jo****@not.for.spamwrote in message
news:um**************@TK2MSFTNGP02.phx.gbl...
>>Peter, like I, comes from a Delphi background; a language which allows
code
before the call to the inherited constructor.

When you have used a language like Delphi or C++ that allows this
practice,

This capability is not available in C++, IIRC.
...

I would say so also. Overriden virtual member function in derived class
should not be called at all. It should call the base version. Which kind
of makes sense, because derived object is not constructed yet.
This is an interesting difference between C++ and C#. In C++ the type of
this changes
through the ctor chain; but in C# (and C++/CLI I think) it is the same.

Which, of course, is why calling virtual methods in ctors in C# is tricky:
since some of
the base class ctors might not have been executed, the object may not be
fully constructed.
Jul 21 '06 #29
Peter Morris [Droopy eyes software] <pe**@droopyeyes.no.com.spam>
wrote:
Actually, having reread your statement, mine indeed doesn't follow.
However, the fact that variables can be set before the base class
constructor is executed shows that to some extent at least, the object
*does* exist - the memory must have been allocated, at least, otherwise
those variables wouldn't exist.

Yes, a good point! So the object *does* exist before the base is called,
and the constructors are merely initialisation code?
Yup.
Like the ways we've already shown, executing static methods etc.

They reek too much of "workaround" though don't you think? I think you
should look at code and see the purpose, not look at it and have to try to
understand why it looks so weird.
Agreed. I'm not sure I'm qualified to comment on why it is the way it
is though - there may well be good reasons we haven't thought of.

--
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
Jul 21 '06 #30
Thomas T. Veldhouse <ve*****@yahoo.comwrote:
| I usually find there are ways round this when I really want to do
| something before the constructor code is executed.

Like... ?
Like the ways we've already shown, executing static methods etc.

Static methods do not get around the problem, because they can not be virtual
[if they could, by definition, they could not be static].
I see no indication that virtual methods are required in any of Peter's
situations.

--
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
Jul 21 '06 #31
Jon Skeet [C# MVP] <sk***@pobox.comwrote:
>
I see no indication that virtual methods are required in any of Peter's
situations.
Sure, as long as everything that is "persisted" is scoped such that it is
available to the static method. So, are you indicating that all instances
that make up his composite object graph be scoped to at least "internal"?

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

Jul 21 '06 #32
Thomas T. Veldhouse <ve*****@yahoo.comwrote:
I see no indication that virtual methods are required in any of Peter's
situations.

Sure, as long as everything that is "persisted" is scoped such that it is
available to the static method. So, are you indicating that all instances
that make up his composite object graph be scoped to at least "internal"?
I don't see why that's required. The only thing you lose is the ability
to change the filtering logic (or validation, or whatever) on a per-
derived-class basis - and there's no indication that that's required.

Could you give an example using Peter's template code as a starting
point of what couldn't be done?

--
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
Jul 21 '06 #33
Jon Skeet [C# MVP] wrote:
....
>
Actually, having reread your statement, mine indeed doesn't follow.
However, the fact that variables can be set before the base class
constructor is executed shows that to some extent at least, the object
*does* exist - the memory must have been allocated, at least, otherwise
those variables wouldn't exist.
....
Yes (at least in C++, memory is allocated for whole object to avoid
obvious problems), however, class may not be in valid state (it could be
in state where invariants do not hold). I don't mean some internal CLR
state, but state visible to it's clients. Calling a method when the
invariants may not hold is risky. It can create lot of maintanance
problems later (when somebody changes something not knowing method is
called before derived construtor has been executed). I'd avoid it at if
I can.

Regards,
Goran
Jul 21 '06 #34
A *very* basic case, it may not make sense but it is a simplified example.

public class PersistentObject
{
public readonly object ObjectSpace;
public PersistentObject(object objectSpace)
{
this.ObjectSpace = objectSpace;
AfterConstruction();
}

protected virtual void AfterConstruction() {}
}

public class Customer : PersistentObject
{
public readonly object Country;
public Customer(PersistentObject country) : base(country.ObjectSpace)
{
this.Country = country;
}

protected override void AfterConstruction()
{
//Do something with this.Country
}
}
If I could call the base constructor after setting this.Country then it
would work perfectly.
Pete
Jul 21 '06 #35
Peter Morris [Droopy eyes software] <pe**@droopyeyes.no.com.spam>
wrote:
A *very* basic case, it may not make sense but it is a simplified example.
Okay, I see your point. If you want a really, really grotty hack way of
solving it, I've got one - but it's so shameful that I'll keep it to
myself unless pressed :)

In general though, I'd strongly recommend avoiding calling virtual
methods from constructors, for the reasons Goran stated - it's hard to
guarantee that appropriate invariants etc are in place before the
object is fully constructed.

--
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
Jul 21 '06 #36
Okay, I see your point. If you want a really, really grotty hack way of
solving it, I've got one - but it's so shameful that I'll keep it to
myself unless pressed :)
*press*press*press* :-)

In general though, I'd strongly recommend avoiding calling virtual
methods from constructors, for the reasons Goran stated - it's hard to
guarantee that appropriate invariants etc are in place before the
object is fully constructed.
In my example a new constructor is introduced in order to ensure that
"Customer" is passed to the new instance, then the original ObjectSpace
constructor is called.

PersistentObject's constructor will keep a reference to the ObjectSpace and
then register this object with the object space

this.ObjectSpace.RegisterInstance(this);

The object space knows if it is loading from the persistence service or not
(the object doesn't on account it doesn't know it is even persistent), if
the object is created as a result of a fetch then it is simply instantiated,
if the persistence service is not loading objects then this is a new
instance so the virtual AfterConstruction is called.

AfterConstruction is a method that is only ever called the very first time
an object is created so that it may initiate composite object instances (eg,
Customer.Address), when it is "recreated" from DB these objects will already
exist and therefore not need creating.

I just thought I'd explain why this virtual method exists, basically it is
so that I don't have to have code like this in my constructors

......
{
if (!ObjectSpace.IsLoading)
{
this.Address = new Address(ObjectSpace);
}
}

I don't like my objects to know about persistence if at all possible.
Pete
Jul 23 '06 #37
Peter Morris [Droopy eyes software] <pe**@droopyeyes.no.com.spam>
wrote:
Okay, I see your point. If you want a really, really grotty hack way of
solving it, I've got one - but it's so shameful that I'll keep it to
myself unless pressed :)

*press*press*press* :-)
Use a thread-local (static) variable which is set in the static method
(see other solutions for how to introduce a call to a static method),
and then use it in the overridden method to populate the instance
variable.

Now excuse me while I wash my hands ;)
In general though, I'd strongly recommend avoiding calling virtual
methods from constructors, for the reasons Goran stated - it's hard to
guarantee that appropriate invariants etc are in place before the
object is fully constructed.

In my example a new constructor is introduced in order to ensure that
"Customer" is passed to the new instance, then the original ObjectSpace
constructor is called.
<snip>
I just thought I'd explain why this virtual method exists, basically it is
so that I don't have to have code like this in my constructors

.....
{
if (!ObjectSpace.IsLoading)
{
this.Address = new Address(ObjectSpace);
}
}

I don't like my objects to know about persistence if at all possible.
But aren't you effectively introducing that anyway by having the
AfterConstruction method at all? You've got to explain why the
AfterConstruction method is present, and moving the logic to the
constructor just makes it more explicit (and therefore easier to
understand, IMO.)

I'm probably missing more though - it's late and I'm tired :(

--
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
Jul 23 '06 #38
Joanna Carter [TeamB] wrote:
Delphi, C#'s [spiritual] parent
[...] does allow code before inherited constructor calls.
Perhaps someone could ask Anders Heljsberg why he changed his mind about
this?
--
Larry Lard
la*******@googlemail.com
The address is real, but unread - please reply to the group
For VB and C# questions - tell us which version
Jul 24 '06 #39
Perhaps someone could ask Anders Heljsberg why he changed his mind about
this?
You know, that would be a really interesting question to see an answer to!
Jul 24 '06 #40
Maybe this gives some hints:
(from http://blogs.msdn.com/scottwil/archi...14/353177.aspx)
"
Q:

would expect C# to either (a) call the base class method if the derived
class is not fully constructed (which seems bad), or (b) provide a syntax
for initializing derived class members using constructor arguments before
base class constructors run (which seems good, and is what C++ does).

My two questions to you are then:

a.. what's up with this? Is there some goodness here that I'm missing out
on? Because this seems like a big old gotcha waiting to happen, calling
virtual methods before the object is constructed.
b.. any thoughts on how my tester buddy Ian can make his derived class
work without petitioning the owner of the base class to stop calling virtual
methods from the constructor?
Thanks!

Eric
A:

We (C#, .NET guidelines, FxCop) discourage calling virtual methods from
constructors. Forbidding it outright would be hard to do--even if we only
allowed constructors to call non-virtual methods, those methods could in
turn call virtuals. Also, it is occasionally useful.

C++ takes an object through a progression of type identities as a
constructor executes--basically, each constructor updates the v-table after
its call to the base constructor returns. As a result, virtual calls in a
constructor never go deeper than the constructor's level of inheritance.
This scheme provides a certain amount of protection against observing
uninitialized instance variables in virtual methods, but I don't think it is
a particularly useful or intuitive model. Indeed, the notion that an object
goes through a progression of base types until it finally reaches its true
type (and vice versa on destruction) is rather odd, and you could even argue
incorrect.

Unlike C++, C# (or, more correctly, .NET) immediately assigns a newly
allocated object its true type. Thus, virtual call dispatch is consistent
across the entire lifetime of the object, but it is possible to receive
virtual calls before execution reaches a constructor body. The big
difference between C++ and .NET is that .NET always zeroes out the memory of
a newly allocated object before executing any constructor code. So, while
virtual methods may observe the zeroed out state of instance variables, they
will never observe an undefined state and type safety is not compromised.

BTW, .NET's behavior is consistent with most other OOP systems, Java
included. In fact, I don't know of any language but C++ that uses the
"multiple personalities" approach to object construction.

Anders

"

"Larry Lard" <la*******@googlemail.comha scritto nel messaggio
news:4i************@individual.net...
Joanna Carter [TeamB] wrote:
>Delphi, C#'s [spiritual] parent
[...] does allow code before inherited constructor calls.

Perhaps someone could ask Anders Heljsberg why he changed his mind about
this?
--
Larry Lard
la*******@googlemail.com
The address is real, but unread - please reply to the group
For VB and C# questions - tell us which version

Jul 24 '06 #41
There is also a little analysis of C# constructors at JOT (an old one but
still actual AFAIK):

http://www.jot.fm/issues/issue_2002_11/article4

"Larry Lard" <la*******@googlemail.comha scritto nel messaggio
news:4i************@individual.net...
Joanna Carter [TeamB] wrote:
>Delphi, C#'s [spiritual] parent
[...] does allow code before inherited constructor calls.

Perhaps someone could ask Anders Heljsberg why he changed his mind about
this?
--
Larry Lard
la*******@googlemail.com
The address is real, but unread - please reply to the group
For VB and C# questions - tell us which version

Jul 24 '06 #42
Jon Skeet [C# MVP] <sk***@pobox.comwrote:
Peter Morris [Droopy eyes software] <pe**@droopyeyes.no.com.spam>
wrote:
Okay, I see your point. If you want a really, really grotty hack way of
solving it, I've got one - but it's so shameful that I'll keep it to
myself unless pressed :)

*press*press*press* :-)

Use a thread-local (static) variable which is set in the static method
(see other solutions for how to introduce a call to a static method),
and then use it in the overridden method to populate the instance
variable.

Now excuse me while I wash my hands ;)
That still doesn't get "customer" set. Further, what you describe is a
blatant hack .. no offense intended.
But aren't you effectively introducing that anyway by having the
AfterConstruction method at all? You've got to explain why the
AfterConstruction method is present, and moving the logic to the
constructor just makes it more explicit (and therefore easier to
understand, IMO.)
While a method called "AfterConstruct" leads one down a logical path towards a
specific business case, there are many cases where a similar pattern may be
required or desired and .NET does not allow its implementation [in spite of
hacking in a thread safe static method to set a static variable when in fact
you want an instance based variable set that cares less about threads and in
fact the base class doesn't know about].

--
Thomas T. Veldhouse
Key Fingerprint: 2DB9 813F F510 82C2 E1AE 34D0 D69D 1EDC D5EC AED1

Jul 24 '06 #43
Thomas T. Veldhouse <ve*****@yahoo.comwrote:
Use a thread-local (static) variable which is set in the static method
(see other solutions for how to introduce a call to a static method),
and then use it in the overridden method to populate the instance
variable.

Now excuse me while I wash my hands ;)

That still doesn't get "customer" set.
It does get customer set - in the overridden method.
Further, what you describe is a blatant hack .. no offense intended.
None taken, as I pointed that out myself :)
But aren't you effectively introducing that anyway by having the
AfterConstruction method at all? You've got to explain why the
AfterConstruction method is present, and moving the logic to the
constructor just makes it more explicit (and therefore easier to
understand, IMO.)

While a method called "AfterConstruct" leads one down a logical path towards a
specific business case, there are many cases where a similar pattern may be
required or desired and .NET does not allow its implementation [in spite of
hacking in a thread safe static method to set a static variable when in fact
you want an instance based variable set that cares less about threads and in
fact the base class doesn't know about].
It's true that it cuts out some patterns - but in my experience it's
not often hugely annoying. YMMV, of course.

--
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
Jul 24 '06 #44
I agree that the way dotnet creates the object instance is correct (it is
how he did it in Delphi too) but I also think that advising against calling
virtual methods from constructors is only due to the fact that you cannot
specify exactly when to call the base constructor's code.

If dotnet would allow me to specify exactly when the base was called then
this recommendation could be dropped. I also think it would make writing
classes much more flexible, in fact I cannot see a negative effect of
changing this.
Pete
Jul 25 '06 #45
Well, I tried but An**************@borland.com doesn't seem to be a genuine
email address :-)
Jul 25 '06 #46
But aren't you effectively introducing that anyway by having the
AfterConstruction method at all? You've got to explain why the
AfterConstruction method is present, and moving the logic to the
constructor just makes it more explicit (and therefore easier to
understand, IMO.)
No matter which constructor is called for a class (there may be many) there
are certain common operations which need to be executed

Customer.Address = new Address(ObjectSpace);
Customer.SomeOtherCompositeObject = .........
etc

This is a common requirement for many of my persistence objects so adding a
virtual method into the base persistent class makes perfect sense. If it
weren't called from a constructor then this is exactly how anybody would do
it - introduce common behaviour into a base class.

The pattern becomes very simple, instead of having code like this in
numerous base classes

{constructor}
CreateCompositeObjects();

private void CreateCompositeObjects()
{
if (!ObjectSpace.IsLoading)
{
....
}
}
All I have to do is to override AfterConstruction
protected override void AfterConstruction
{
...
}

If AfterConstruction is only called on "new" objects rather than fetched
objects being reinstanciated then I can effectively pretend that my objects
are not persistent at all. Separation is very important for keeping
business classes "clean", when was the last time you got into your car and
Saved it? :-)

Pete
Jul 25 '06 #47
It does get customer set - in the overridden method.

I don't really understand your suggestion. Is there any chance of some
suedo code?
Jul 25 '06 #48
I think that the constructor behavior in .NET is just what is needed.
I mean, it's predictable, one way only and safe. It's quite uncommon, IMHO,
that there are other needs.
Dangling runtime initialization is somewhat risky as I see it, and harder to
manage.
And for the uncommon needs there are usually quite clean workaround.

"Peter Morris [Droopy eyes software]" <pe**@droopyeyes.no.com.spamha
scritto nel messaggio news:Oz**************@TK2MSFTNGP03.phx.gbl...
>I agree that the way dotnet creates the object instance is correct (it is
how he did it in Delphi too) but I also think that advising against calling
virtual methods from constructors is only due to the fact that you cannot
specify exactly when to call the base constructor's code.

If dotnet would allow me to specify exactly when the base was called then
this recommendation could be dropped. I also think it would make writing
classes much more flexible, in fact I cannot see a negative effect of
changing this.
Pete

Jul 25 '06 #49
Peter Morris [Droopy eyes software] <pe**@droopyeyes.no.com.spam>
wrote:
It does get customer set - in the overridden method.

I don't really understand your suggestion. Is there any chance of some
suedo code?
Sure.

using System;

public class Base
{
public Base()
{
AfterConstruction();
}

public virtual void AfterConstruction()
{
}
}

public class Derived : Base
{
[ThreadStatic]
static string temporaryName;

string m_name;

public Derived(string name) : this (SetStatic(name))
{
Console.WriteLine ("Now I'm in my own constructor");
}

Derived (int ignored)
{
}

static int SetStatic (string name)
{
temporaryName = name;
return 0;
}

public override void AfterConstruction()
{
m_name = temporaryName;
Console.WriteLine ("Validating name="+m_name);
}
}

class Test
{
static void Main()
{
Derived d = new Derived("fred");
}
}

The upshot is that in AfterConstruction which is called from the base
class, you can still have the arguments to derived constructor
available.

--
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
Jul 25 '06 #50

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Rajesh Garg | last post by:
Can we have private constructors and destructors? IF yes what is the use of such constructors or destructors.....in the sense where can these be implemented in a system................. I have...
42
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...
6
by: Stephen Martinelli | last post by:
thanks for the help...just one more question.... can a class have more then two parameterized constructors?..i would like to be able to instanciate the class with a different number of...
4
by: Sathyaish | last post by:
What is a private constructor, and why would a class have one? What are the other kinds of constructors besides: (1) public constructors; and (2) parameterized constructors And I understand...
10
by: John | last post by:
Trying to find out what is essential / optional, I made an extremely simple Class and Module combination to add two numbers. (see below) It appears that an empty constructor is needed n order to...
3
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...
22
by: Peter Morris [Droopy eyes software] | last post by:
Look at these two classes public class Test { public readonly string Name; public Test(string name)
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
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
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
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
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 ...

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.