We help IT Professionals succeed at work.

Static classes with static constructor throws: "The type initializer for 'class' threw an exception" , but debugger sees the data...

Matt_Du
Matt_Du asked
on
2,096 Views
Last Modified: 2013-12-16
I am trying to use a static class I named 'universal' which contains reference strings and a dictionary<string,string>. The idea is to be able to access these from anywhere in my program when i need to. I used a static constructor in my static class to parse the command line arguments and this works (At least while debugging hovering over the variables with the mouse displays the expected data). This is in SECTION 1 of the code snippet below.

In SECTION 2, I try to access the data and every time, I get the following exception:

System.TypeInitializationException was unhandled
  Message="The type initializer for 'TSP.universals' threw an exception."
  Source="TSP"
  TypeName="TSP.universals"
  StackTrace:
       at TSP.formMain.setLabels() in e:\p4\qa\integrated\nftc\TSP\TSP\formMain.cs:line 28
       at TSP.formMain..ctor() in e:\p4\qa\integrated\nftc\TSP\TSP\formMain.cs:line 38
       at TSP.Program.Main(String[] args) in e:\p4\qa\integrated\nftc\TSP\TSP\Program.cs:line 20
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Collections.Generic.KeyNotFoundException
       Message="The given key was not present in the dictionary."
       Source="mscorlib"
       StackTrace:
            at System.ThrowHelper.ThrowKeyNotFoundException()
            at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
            at TSP.universals..cctor() in e:\p4\qa\integrated\nftc\TSP\TSP\claParse.cs:line 63
       InnerException:

What is even weirder though is that with the debugger, the data is there!! (See screenshot)

Thanks for the help!


/* PORTION 1 */
 
namespace TSP
{
    public static class universals
    {
        private static readonly string _defaultDataSource = @"\\platformtesting.com\filehub";
        private static readonly int _defaultPartitionSize = 36864;
 
        private static string sysdrive = Environment.GetEnvironmentVariable("SystemDrive");
        private static string sysroot = Environment.GetEnvironmentVariable("SystemRoot");
        private static string machineName = Environment.GetEnvironmentVariable("COMPUTERNAME");
 
        public static Dictionary<string, string> cla_table = new Dictionary<string,string>();
 
        static universals()
        {
            string[] args = Environment.GetCommandLineArgs();
            // For all CLA, remove spaces,convert '=' -> ':' and otherwise
            for (int temp_a = 0; temp_a < args.Length; temp_a++)
            {
                args[temp_a] = args[temp_a].ToLower();
                args[temp_a] = args[temp_a].Replace("=", ":");
                args[temp_a] = args[temp_a].Replace("\\", "-");
                args[temp_a] = args[temp_a].Replace("/", "-");
                args[temp_a] = args[temp_a].Replace(" ", "-");
            }
            foreach (string arg in args)
            {
                cla_table.Add(arg.Substring(1, arg.IndexOf(":") - 1), arg.Substring(arg.IndexOf(":") + 1));
            }
            // Checks performed here
            if (!cla_table.ContainsKey("datasource")) cla_table.Add("datasource", universals._defaultDataSource);
        }
    }
}
 
/* PORTION 2 */
namespace TSP
{
    public partial class formMain : Form
    {
        delegate void delegateListBoxAddItem(string Message);
 
        public void ListBoxAddItem(string Message)
        {
            this.listBoxMain.Items.Add(string.Format("{0} : {1}", DateTime.Now.ToString(), Message));
            this.listBoxMain.SelectedIndex = listBoxMain.Items.Count - 1;
        }
        public void setLabels()
        {
            labelDataSourceA.Text = universals.cla_table["datasource"];
        }
        public formMain()
        {
            InitializeComponent();
            setLabels();
        }
	}
}

Open in new window

weirdError.png
Comment
Watch Question

private static readonly string _defaultDataSource

Your variable is private, try changing it to public
Can you also try putting a try / catch statement inside the constructor, I have a feeling something is going wrong in there.
try{ 
            string[] args = Environment.GetCommandLineArgs();
            // For all CLA, remove spaces,convert '=' -> ':' and otherwise
            for (int temp_a = 0; temp_a < args.Length; temp_a++)
            {
                args[temp_a] = args[temp_a].ToLower();
                args[temp_a] = args[temp_a].Replace("=", ":");
                args[temp_a] = args[temp_a].Replace("\\", "-");
                args[temp_a] = args[temp_a].Replace("/", "-");
                args[temp_a] = args[temp_a].Replace(" ", "-");
            }
            foreach (string arg in args)
            {
                cla_table.Add(arg.Substring(1, arg.IndexOf(":") - 1), arg.Substring(arg.IndexOf(":") + 1));
            }
            // Checks performed here
            if (!cla_table.ContainsKey("datasource")) cla_table.Add("datasource", universals._defaultDataSource);
}
catch(Exception e){
   //put a break point here
   Console.WriteLine(e.Message);
}

Open in new window

Author

Commented:
Woops posted the wrong pic.
In reply to rishadanPort, the same thing occurs with something that is public

As the new screenshot shows and the orignal code as well.





woops.jpg
It might be helpful if you first try making this work without having a static class. And after you think it works with a normal non static class, then try making it into a static class.
"Static constructor is used to initialize static data members as soon as the class is referenced first time".

So basically, it ran thru the constructor before this variable was taken, and the constructor threw an error.
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
like for example at this line:
cla_table.Add(arg.Substring(1, arg.IndexOf(":") - 1),

if the arg string did not contain the ":" an error would occur.
Top Expert 2004

Commented:
The constructor is definitely throwing an exception ... you should be able to look at the innerexception of the exception you are getting as to what is going wrong.


Author

Commented:
Yeah thanks, I figured it out --

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.