simple question

T

Tony Johansson

Hello!

Assume I have this class Person below.
My question is if it's any point to have like in my example this row
randomNumberGenerator = new Random();
in the c-tor
I mean it will be just the same if I remove the c-tor and change this row
private Random randomNumberGenerator;
to this row
private Random randomNumberGenerator = new Random();

My second question is if it's good programming to move statement from a
c-tor if I don't
pass any argument and place them as instance variable like I did above.

class Person
{
private Random randomNumberGenerator;

public Person
{
randomNumberGenerator = new Random();
}

....
....
}

//Tony
 
G

Göran Andersson

Tony said:
Hello!

Assume I have this class Person below.
My question is if it's any point to have like in my example this row
randomNumberGenerator = new Random();
in the c-tor
I mean it will be just the same if I remove the c-tor and change this row
private Random randomNumberGenerator;
to this row
private Random randomNumberGenerator = new Random();

My second question is if it's good programming to move statement from a
c-tor if I don't
pass any argument and place them as instance variable like I did above.

class Person
{
private Random randomNumberGenerator;

public Person
{
randomNumberGenerator = new Random();
}

...
...
}

//Tony

Yes, it's the same. The code to intialise the variable will
automatically be added to every constructor in the class.

A (non-static) class always has a constructor, if you don't declare a
constructor, a constructor is created automatically. That's where the
initialising code is placed if you haven't declared a constructor.

If you declare a constructor, you might want to put the initialisation
in it, so that it's clearer when and where it happens.
 
F

Family Tree Mike

Tony Johansson said:
Hello!

Assume I have this class Person below.
My question is if it's any point to have like in my example this row
randomNumberGenerator = new Random();
in the c-tor
I mean it will be just the same if I remove the c-tor and change this row
private Random randomNumberGenerator;
to this row
private Random randomNumberGenerator = new Random();

My second question is if it's good programming to move statement from a
c-tor if I don't
pass any argument and place them as instance variable like I did above.

class Person
{
private Random randomNumberGenerator;

public Person
{
randomNumberGenerator = new Random();
}

....
....
}

//Tony


.

In this case, I don't believe it matters. In general, I would put the
initializations in a startup routine called by the constructor(s).

Consider this case, as a reason why:

class Failure
{
private SomeType st = new SomeType(); // throws an exception...

public Failure()
{
// if i initialize 'st' here, I can catch the failure here.
}
}

But as I said, Random() won't throw an exception on initialization, so it
shouldn't matter there.

Mike
 
T

Tony Johansson

Family Tree Mike said:
In this case, I don't believe it matters. In general, I would put the
initializations in a startup routine called by the constructor(s).

Consider this case, as a reason why:

class Failure
{
private SomeType st = new SomeType(); // throws an exception...

public Failure()
{
// if i initialize 'st' here, I can catch the failure here.
}
}

But as I said, Random() won't throw an exception on initialization, so it
shouldn't matter there.

Mike

OK I can see the advantage of using the c-tor when an exception can be
thrown

//Tony
 
P

Peter Duniho

Tony said:
Family Tree Mike said:
Tony Johansson said:
[...]
My question is if it's any point to have like in my example this row
randomNumberGenerator = new Random();
in the c-tor
I mean it will be just the same if I remove the c-tor and change this row
private Random randomNumberGenerator;
to this row
private Random randomNumberGenerator = new Random(); [...]

My second question is if it's good programming to move statement from a
c-tor if I don't
pass any argument and place them as instance variable like I did above.
[...]

In this case, I don't believe it matters. In general, I would put the
initializations in a startup routine called by the constructor(s).
[...]

OK I can see the advantage of using the c-tor when an exception can be
thrown

_If_ you can do something useful with the exception and continue
initializing. In most cases, that won't be true.

As for the original question, normally it won't matter much. But IMHO
it's important to understand that the replies you've gotten aren't
literally correct. Specifically, member field initializers are in fact
handled differently from initialization in the constructor.

They aren't simply moved into the constructor. Rather, a more explicit
initialization is constructed from your declarations, that looks
something like the following. From something like this:

class A
{
public A()
{
// stuff
}
}

class B : A
{
private readonly int = 5;

public B()
{
// other stuff
}
}

…the class B construction winds up looking more like this:

ActualBConstruction()
{
ExecuteInitializers();
base(); // execute base constructor
this(); // execute this constructor
}

In other words, all of the member field initialization is done first,
from most-derived class to least, then followed by the execution of the
base class constructors, from least-derived class to most (i.e. in the
opposite order), finally followed by the actual constructor you wrote.

As I said, normally it doesn't matter much. You can initialize the
object either in the constructor or in the member field initializer
according to your own preference for how the code is laid out.

But if there are important side-effects to object construction for a
type, either because the constructor itself has side-effects, or because
it's the first time the type has been used and there's static
initialization in the class (which IMHO is basically always something to
consider as a side-effect), the order of those side-effects are not the
same as the order of the rest of the object constructor logic.

Finally, note my use of "readonly". Often when you are initializing a
member field like that, it's because the field will have the same value
throughout the lifetime of the class instance. Any time that's true,
you should go ahead and use "readonly" to make that explicit (you can
initialize "readonly" fields in a constructor…they just can't be changed
later).

Pete
 
A

Arne Vajhøj

Hello!

Assume I have this class Person below.
My question is if it's any point to have like in my example this row
randomNumberGenerator = new Random();
in the c-tor
I mean it will be just the same if I remove the c-tor and change this row
private Random randomNumberGenerator;
to this row
private Random randomNumberGenerator = new Random();

You will end up with the same.
My second question is if it's good programming to move statement from a
c-tor if I don't
pass any argument and place them as instance variable like I did above.

class Person
{
private Random randomNumberGenerator;

public Person
{
randomNumberGenerator = new Random();
}

...
...
}

If all the assignments are trivial (no potential exceptions,
no method calls, no interdependencies etc.) and you can avoid
the explicit constructor completely by doing so then it is fine.

In all the more complex cases I strongly recommend putting
all the assignments in the constructor. It is a lot more
readable. Everybody will understand the order of initialization,
because the lines in the constructor get executed sequentially.
Otherwise the reader will have to study the language specification
carefully to understand the order of initialization.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top