• Advertisement
Sign in to follow this  

[.net] Static Member Initialization

This topic is 3035 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can someone tell me please why the heck C# initializes my static member whenever the class is instantiated? I'm not calling the member initialization code in the constructor, it's only declared as a static, and have the initialization in a static method. Actually it's a dictionary that I initialize once by calling that static method. Then Whenever I create an object of that class, the dictionary is set to null/cleared... Is there a way to prevent this "default" initialization of static member? Help appreciated.

Share this post


Link to post
Share on other sites
Advertisement
Actually at some point of the program the object is disposed somehow...what the heck...I cannot even track down the object status because of VS debugging limitations...

Share this post


Link to post
Share on other sites
Quote:

Can someone tell me please why the heck C# initializes my static member whenever the class is instantiated? I'm not calling the member initialization code in the constructor, it's only declared as a static, and have the initialization in a static method. Actually it's a dictionary that I initialize once by calling that static method. Then Whenever I create an object of that class, the dictionary is set to null/cleared...

Post your code. The way you have described this problem makes little sense and suggests that you might be misusing or overloading a term.

Quote:

Actually at some point of the program the object is disposed somehow...what the heck...I cannot even track down the object status because of VS debugging limitations...

The debugger is very powerful. Don't confuse your lack of understanding of it with limitations on its part. You can watch managed objects out of scope by putting them in the watch window when they are in scope, right clicking them and choosing "make object ID." This will put {n#} after the object's value in the value column of the watch window (where n is some number, probably 1). Then you can type "1#" (no quotes) into the watch window and see that object regardless of whether or not you have a reference to that object in scope where execution is broken. You can track changes to an object pretty easily this way, and with conditional breakpoints.

Share this post


Link to post
Share on other sites
I dunno what a test case I can use here. Debug break point cannot help trap any background event causing this object's destruction. It's static!!!!
Cannot keep watches of that object since they get lost as soon as the debug point is outside the module...

Share this post


Link to post
Share on other sites
Ok I set the watch, and it seems that the object is freed and set to null as soon as the class is instantiated and a non-static member is initialized.

Posting code? Hmmmm nope...it's huge.

Share this post


Link to post
Share on other sites
Example Testcase: Preferably minimal source code that reproduces the error.

Quote:
It's static!!!!

Calm.


Quote:
Posting code? Hmmmm nope...it's huge.

See this. If not, no help.

Share this post


Link to post
Share on other sites
Quote:

I dunno what a test case I can use here.

The code for the class containing the static member in question, and one of the lines of code that instantiates an instance of that class in a way that causes your bug.

Quote:

Debug break point cannot help trap any background event causing this object's destruction. It's static!!!!

I doubt the object is being destroyed, you're misusing that term. You seem to really be claiming the static member that is a reference to that object is being set to null somewhere. A breakpoint can help you track this down; the member being static has nothing to do with it.

Quote:

Cannot keep watches of that object since they get lost as soon as the debug point is outside the module...

Yes, you can, using the method of tracking object IDs I described above. That's what it's there for. It maps a user-friendly ID to the object's internal handle inside the CLR. It's reliable.

Quote:

Ok I set the watch, and it seems that the object is freed and set to null as soon as the class is instantiated and a non-static member is initialized.

If something is setting the reference to null, that doesn't mean the underlying object is being freed, that's not how the GC works.

Quote:

Posting code? Hmmmm nope...it's huge.

Then you get no help. We cannot read your mind. Post the code I asked for in the beginning of this reply. Or a minimal reproduction case as phresnel is asking for. Without that we can't help you any further.

Share this post


Link to post
Share on other sites
I tried to create little code that samples the problem...but it worked. I think now the complexity of the program confuses the GC somehow...until it's my fault, it's the GC :D

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
interface IAAA
{
Dictionary<string, int> X { get; }
}

class AAA : IAAA
{
private static Dictionary<string, int> x;

private Dictionary<string, int> y = new Dictionary<string,int>();

public static void Init()
{
x = new Dictionary<string,int>();
x["A"] = 10;
x["B"] = 20;
x["C"] = 30;
}

public Dictionary<string, int> X
{
get { return x; }
}
}

class Program
{
static void Main( string[] args )
{
AAA.Init();

IAAA a = new AAA();

Console.WriteLine( a.X["A"] );
Console.WriteLine( a.X["B"] );
Console.WriteLine( a.X["C"] );
}
}
}


X object is reinitialized...so after the the call new AAA(), the output is no longer 10, 20, 30 :)

This code works but my program does not.

Share this post


Link to post
Share on other sites
And i looked everywhere in the program there's no evidence of setting this dictionary to null, nor it's cleared.

Share this post


Link to post
Share on other sites
Quote:

I tried to create little code that samples the problem...but it worked. I think now the complexity of the program confuses the GC somehow...until it's my fault, it's the GC :D

This is an extremely naive and useless attitude; you're making accusations that do not make any sense at all given how the GC works. It is extremely unlikely that the object would be collected so fast unless you are forcing it to. Having a reference become null does not mean the object is collected or even that the object is eligible for collection. A poor workman blames his tools.

It's highly unlikely that your code is complex enough to expose a bug in the garbage collector.

Quote:

I tried to create little code that samples the problem...but it worked.

Then the problem is elsewhere. Show us your code.

Share this post


Link to post
Share on other sites
1. Use source tags to make your code readable.

2. You can't post working code and expect us to extrapolate to your broken program. You can be sure of this however: it's most certainly your fault and not the GC's.

3. If you continue to be less than helpful, people are going to stop responding and you'll get nowhere.

Share this post


Link to post
Share on other sites
Found it!

The static constructor is called every time I Instantiate the class. How come?

Share this post


Link to post
Share on other sites
Quote:

And i looked everywhere in the program there's no evidence of setting this dictionary to null, nor it's cleared.

If your code at least approximates your functional example, it's entirely possible that you could be calling IAAA.get_X() before you call the static AAA .Init() method on AAA. Which would leave AAA.x its default value (null), and thus exhibit this problem.

How are you validating that your static Init() is called before you access the property backed by the member variable? Show us your code.

Share this post


Link to post
Share on other sites
Quote:

The static constructor is called every time I Instantiate the class. How come?

The static constructor is called once per type per application domain. I can provide no more information without seeing your code.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sambori
Found it!

The static constructor is called every time I Instantiate the class. How come?

From the C# standard:

Quote:
The static constructor for a non-generic class executes at most once in a given application domain. The static constructor for a generic class declaration executes at most once for each closed constructed type constructed from the class declaration (§25.1.5). The execution of a static constructor is triggered by the first of the following events to occur within an application domain:
• An instance of the class is created.
• Any of the static members of the class are referenced.

Share this post


Link to post
Share on other sites
I wish I could post my code, it's not mine...it's a big project I'm working on.

I tried to sample the situation in a smaller program, but it seems it works.

Now the static constructor is called whenever an object is instantiated.

If i move the static member initialization code to a static function I call upon the start of the program, the static member is set to null upon instantiation of the class.

Share this post


Link to post
Share on other sites
Quote:

Now the static constructor is called whenever an object is instantiated.

The standard guarantees that the static constructor for a type is called at most once per application domain; it should be called before any static methods on that type execute as well. You should not be seeing it execute twice, normally, nor should it be possible for it to execute before your own static methods.

Quote:

I wish I could post my code, it's not mine...it's a big project I'm working on.

You only need to post the code for this class in question. This is the last time I'm going to ask you.

Share this post


Link to post
Share on other sites
No, it isn't. Your analysis of the problem is incorrect; the static constructor is not being called more than once and will not get called before any other code in that class executes. You have not solved anything, only stuck your fingers in your ear and exclaimed "LA LA I CAN'T HEAR YOU!"

But if you chose to live in ignorance, I suppose that's your problem.

Share this post


Link to post
Share on other sites
I guess I am getting in the discussion a little late.

By reviewing your code, I'd suggest you use in-property initialization, or, even better, a singleton.

By in-property initialization, I mean:

interface IDictionaryContainer
{
Dictionary<string, int> Container { get; }
}

class DictionaryContainer : IDictionaryContainer
{
private static Dictionary<string, int> singletonContainer;

public Dictionary<string, int> Container
{
get
{
if (singletonContainer == null)
{
singletonContainer = new Dictionary<string, int>();
singletonContainer["ten"] = 10;
singletonContainer["twenty"] = 20;
singletonContainer["thirty"] = 30;
}
return singletonContainer;
}
}
}


I am a developer, but at work I happen to do some support, with a lot worse appreciation for advise or cooperation. So, don't get angry with him/her. He/she probably doesn't care at all, so don't waste your time being angry.

To the thread poster: instead of worrying whether and when your supposed Init method is called, you can do in-property initialization. You get the benefit of always having your property initialized and a little something called late-binding (a kind of, the only stuff that ever gets initialized is the one you use). The drawback is that first operations are going to be slower.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sambori
Calm down rage!


Quote:
Military Coding Handbook, p. 853
[0] You shall not code under heavy artillery fire.
[1] If [0] is not applicable, stay calm and rational. Minefield code is doomed, and so is everyone running your code.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement