473,544 Members | 801 Online
Bytes | Software Development & Data Engineering Community
+ 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 PersistentObjec t and to have
a constructor (ObjectSpace objectSpace) so that objects may be recreated.

PersistentObjec t's constructor will do something like this

this.ObjectSpac e = objectSpace;
objectSpace.Reg isterObjectCrea tion(this);

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

if (!IsLoadingFrom Database)
newInstance.Aft erConstruction( );
The virtual AfterConstructi on 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 : PersistentObjec t
{
public CustomerAction( Customer customer)
: base(customer.O bjectSpace)
{
this.Customer = customer;
}

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

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

1) new CustomerAction( someCustomer);
2) CustomerAction constructor is called
3) Base constructor (customer.Objec tSpace is called)
4) CustomerAction. AfterConstructi on 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
68 3455
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(C ustomer customer) : base(customer)
{
//this class is special so needs some special checks first
if (!DoSpecialChec ks(customer))
throw new SomeExceptionTy pe("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(C ustomer customer)
{
//this class is special so needs some special checks first
if (!DoSpecialChec ks(customer))
throw new SomeExceptionTy pe("The special checks failed");

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

public ChildClass : PersistentObjec t
{
public ChildClass(Cust omer customer)
{
if (customer == null)
throw new ArgumentNullExc eption("ChildCl ass constructor - customer");
if (customer.Objec tSpace == null)
throw new ArgumentExcepti on("ChildClass constructor - customer has no
object space");

base(customer.O bjectSpace);
}
}

So instead of my nicely formatted + (more importantly) expected exception
types I get a NullReferenceEx ception 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**@droopyeye s.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**@droopyeye s.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 : PersistentObjec t
| {
| public ChildClass(Cust omer customer)
| {
| if (customer == null)
| throw new ArgumentNullExc eption("ChildCl ass constructor - customer");
| if (customer.Objec tSpace == null)
| throw new ArgumentExcepti on("ChildClass constructor - customer has no
| object space");
|
| base(customer.O bjectSpace);
| }
| }

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(Cus tomer customer)
{
return customer;
}

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

public CustomerAction( Customer customer) : this(DoSomethin g(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.WriteLi ne ("Base constructor");
}
}

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

public Derived()
{
}

static int MakeSomeCall()
{
Console.WriteLi ne ("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.co m>
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**@droopyeye s.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(C ustomer customer) : base(customer)
{
//this class is special so needs some special checks first
if (!DoSpecialChec ks(customer))
throw new SomeExceptionTy pe("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 : PersistentObjec t
{
public ChildClass(Cust omer customer)
{
if (customer == null)
throw new ArgumentNullExc eption("ChildCl ass constructor - customer");
if (customer.Objec tSpace == null)
throw new ArgumentExcepti on("ChildClass constructor - customer has no
object space");

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

public ChildClass (Customer customer)
: base (RetrieveObject Space(customer) )
{
...
}

static ObjectSpace RetrieveObjectS pace (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.co m>
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(Cus tomer customer)
{
return customer;
}

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

public CustomerAction( Customer customer) : this(DoSomethin g(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.co m>
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******** ******@TK2MSFTN GP02.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.co ma écrit dans le message de news:
MP************* ***********@msn ews.microsoft.c om...

| 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

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

Similar topics

3
21375
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 an idea that we can have private constructors and destructors but am not able to find a situation where they can be used... Regards RVG...
42
5722
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 kind. It sounds simple but evidently .NET has difficulty with this concept for some reason. I do understand that .NET objects are created on the GC...
6
2381
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 argument..... thanks folks steve
4
5034
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 that they are not mutually exclusive of one another. The above classification assimilates my knowledge of having used constructors in both the above...
10
1738
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 work right, although I quite don't see what is does in addition to the 2nd constructor. Also, the example works fine without message calls in...
3
1629
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 permutations for constructors (none, default, two argument) and method call in body of constructor (none and one). Maybe this example is not...
22
5179
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)
0
7424
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
1
7376
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7709
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5909
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
4918
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3415
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3409
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1841
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 we have to send another system
1
988
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.