static vars declared with class instantiation

  • Thread starter Thread starter John A Grandy
  • Start date Start date
J

John A Grandy

Say I have Class1 which contains

static Class2 var1 = new Class2();

Is Class2 constructor code only executed if var1 is referenced in the
code-execution path ?

Or is Class2 constructor code executed on load of any class that references
Class1 ?

Or ... something else ...
 
John said:
Say I have Class1 which contains

static Class2 var1 = new Class2();

Is Class2 constructor code only executed if var1 is referenced in the
code-execution path ?

Or is Class2 constructor code executed on load of any class that references
Class1 ?

Or ... something else ...

I'm assuming, of course, that the code looks something like this:

public Class1
{
static Class2 var1 = new Class2();


}

So that "var1" is effectively a static member of Class1.

Jon Skeet is the instantiation guru, but if memory serves the instance
of Class2 will be constructed and assigned to var1 the first time that
the execution path makes mention of Class1, either by trying to create
an instance or mentioning any static member of Class1.

It's the same as creating a static constructor for Class1: the static
constructor runs on first "mention" of Class1, before anything in the
class is accessible.

I reserve the right to be wrong, though. :-)
 
Hmmm ...

So, I'm kindof guessing here, but seems that Singletons might be much less
relevant in .NET compared with , say , Java ?

A .NET class with a static constructor (or has all its data contained in
static vars that are instantiated on declaration) effectively replaces a
Singleton ... because any instantiation-related work is guaranteed to only
be performed once -- on first reference of the class.
 
So, I'm kindof guessing here, but seems that Singletons might be much less
relevant in .NET compared with , say , Java ?

A .NET class with a static constructor (or has all its data contained in
static vars that are instantiated on declaration) effectively replaces a
Singleton ... because any instantiation-related work is guaranteed to only
be performed once -- on first reference of the class.

Yes (for suitably detailed values of "on first reference") but I'm not
sure why you think that's different to Java, which has broadly the same
semantics.
 
John said:
Hmmm ...

So, I'm kindof guessing here, but seems that Singletons might be much less
relevant in .NET compared with , say , Java ?

A .NET class with a static constructor (or has all its data contained in
static vars that are instantiated on declaration) effectively replaces a
Singleton ... because any instantiation-related work is guaranteed to only
be performed once -- on first reference of the class.

With one hugely important caveat: you can't get a reference to a static
class, so you can't pass it as an argument, return it as a method
result, store it in a collection, etc. Sometimes you want to do these
things with a singleton class. That's why I usually prefer the
singleton pattern to a static class.

As well, if I make something a static class and then later decide my
design was wrong, I'm in for a nightmare. If I make it a singleton and
then decide, for example, that I need to inherit from it and benefit
from polymorphism, well that's easy to fix.
 
Jon Skeet said:
Yes (for suitably detailed values of "on first reference") but I'm not
sure why you think that's different to Java, which has broadly the same
semantics.
 
Hmmm ... well, it looks like I've obtained a misunderstanding of how Java
handles static vars from a design patterns book I won't name.

This book states that the traditional Singleton will have its static vars'
assignment constructors invoked on load of the class ... which I understand
to mean load of the class' assembly.

I'm referring to the example I gave above (which Bruce correctly augmentd).
 
Hmmm ... well, it looks like I've obtained a misunderstanding of how Java
handles static vars from a design patterns book I won't name.

This book states that the traditional Singleton will have its static vars'
assignment constructors invoked on load of the class ... which I understand
to mean load of the class' assembly.

There's no such concept of "assembly" in Java, so that can't be right.

However, the semantics of when a type's initialization occurs is in the
Java language specification. From section 12.4.1:

<quote>
A class or interface type T will be initialized immediately before the
first occurrence of any one of the following:

* T is a class and an instance of T is created.
* T is a class and a static method declared by T is invoked.
* A static field declared by T is assigned.
* A static field declared by T is used and the reference to the
field is not a compile-time constant (§15.28). References to compile-
time constants must be resolved at compile time to a copy of the
compile-time constant value, so uses of such a field never cause
initialization.
</quote>

In other words, it's pretty similar to the C# behaviour when there's a
static constructor present. (When there's no static constructor present
in C#, the CLR has more discretion in terms of exactly when type
initialization occurs.)
 
Once initialized , a static ref to a type retains its instantiated object in
memory until the containing app domain is recycled (either as part of worker
process recycle , or otherwise ) ...

For an asp.net app , I want to use the singleton strictly within the
processing of a single page request ...

( Complex conditional logic in the page processing means that the "Instance"
method or property on the singleton won't necessarily be called , and so the
private member won't necessarily be instantiated. )

If I provide a function that can be called to set the static ref to null (
to dispose of the referred to object before page unload ) , what
complications are there to proper design of a scalable singleton ?


Or is a singleton not the best solution for my design goal .... ?


Hmmm ... well, it looks like I've obtained a misunderstanding of how Java
handles static vars from a design patterns book I won't name.

This book states that the traditional Singleton will have its static vars'
assignment constructors invoked on load of the class ... which I
understand
to mean load of the class' assembly.

There's no such concept of "assembly" in Java, so that can't be right.

However, the semantics of when a type's initialization occurs is in the
Java language specification. From section 12.4.1:

<quote>
A class or interface type T will be initialized immediately before the
first occurrence of any one of the following:

* T is a class and an instance of T is created.
* T is a class and a static method declared by T is invoked.
* A static field declared by T is assigned.
* A static field declared by T is used and the reference to the
field is not a compile-time constant (§15.28). References to compile-
time constants must be resolved at compile time to a copy of the
compile-time constant value, so uses of such a field never cause
initialization.
</quote>

In other words, it's pretty similar to the C# behaviour when there's a
static constructor present. (When there's no static constructor present
in C#, the CLR has more discretion in terms of exactly when type
initialization occurs.)
 
Once initialized , a static ref to a type retains its instantiated object in
memory until the containing app domain is recycled (either as part of worker
process recycle , or otherwise ) ...
Yup.

For an asp.net app , I want to use the singleton strictly within the
processing of a single page request ...

That doesn't sound like it's really a singleton then. It's just
something associated with the request. That's the association you want
to make, along with lazy instantiation presumably. I wouldn't start
trying to make things "real" singletons and then modifying them.

Unfortunately I don't know enough ASP.NET and don't have time to
investigate at the minute to know exactly where you should hook things
in, but I wouldn't have thought it would be too hard.
 
Back
Top