What is and how to fix System.TypeInitializationException error?

[亡魂溺海] 提交于 2019-11-29 05:25:16

Whenever a TypeInitializationException is thrown, check all initialization logic of the type you are referring to for the first time in the statement where the exception is thrown - in your case: Logger.

Initialization logic includes: the type's static constructor (which - if I didn't miss it - you do not have for Logger) and field initialization.

Field initialization is pretty much "uncritical" in Logger except for the following lines:

private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

s_commonAppData is null at the point where Path.Combine(s_commonAppData, "XXXX"); is called. As far as I'm concerned, these initializations happen in the exact order you wrote them - so put s_commonAppData up by at least two lines ;)

System.TypeInitializationException happens when the code that gets executed during the process of loading the type throws an exception.

When .NET loads the type, it must prepare all its static fields before the first time that you use the type. Sometimes, initialization requires running code. It is when that code fails that you get a System.TypeInitializationException.

In your specific case, the following three static fields run some code:

private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

Note that s_bstCommonAppData depends on s_commonAppData, but it is declared ahead of its dependency. Therefore, the value of s_commonAppData is null at the time that the Path.Combine is called, resulting in ArgumentNullException. Same goes for the s_bstUserDataDir and s_bstCommonAppData: they are declared in reverse order to the desired order of initialization.

Re-order the lines to fix this problem:

private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");

These lines are your problem (or at least one of your problems, if there are more):

private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);

You reference some static members in the initializers for other static members. This is a bad idea, as the compiler doesn't know in which order to initialize them. The result is that during the initialization of s_bstCommonAppData, the dependent field s_commonAppData has not yet been initialized, so you are calling Path.Combine(null, "XXXX") and this method does not accept null arguments.

You can fix this by making sure that fields used in the initialization of other fields are declared first:

private static string s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
private static string s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
private static string s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");

Or use a static constructor to explicitly order the assignments:

private static string s_bstCommonAppData;
private static string s_bstUserDataDir;
private static string s_commonAppData;

static Logger()
{
    s_commonAppData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
    s_bstCommonAppData = Path.Combine(s_commonAppData, "XXXX");
    s_bstUserDataDir = Path.Combine(s_bstCommonAppData, "UserData");
}

i. Please check the InnerException property of the TypeInitializationException

ii. Also, this may occur due to mismatch between the runtime versions of the assemblies. Please verify the runtime versions of the main assembly (calling application) and the referred assembly

Jeff

I experienced the System.TypeInitializationException due to a different error in my .NET framework 4 project's app.config. Thank you to pStan for getting me to look at the app.config. My configSections were properly defined. However, an undefined element within one of the sections caused the exception to be thrown.

Bottom line is that problems in the app.config can generated this very misleading TypeInitializationException.

A more meaningful ConfigurationErrorsException can be generated by the same error in the app.config by waiting to access the config values until you are within a method rather than at the class level of the code.

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

namespace ConfigTest
{
    class Program
    {
        public static string machinename;
        public static string hostname;
        public static NameValueCollection _AppSettings;

        static void Main(string[] args)
        {
            machinename = System.Net.Dns.GetHostName().ToLower();
            hostname = "abc.com";// System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).HostName.ToLower().Replace(machinename + ".", "");
            _AppSettings = ConfigurationManager.GetSection("domain/" + hostname) as System.Collections.Specialized.NameValueCollection;
        }
    }
}

If you have custom attributes in appsetting. move your

     <configSections> 
     </configSections>

tag to the first child in the <confuguration>.

I know that this is a bit of an old question, but I had this error recently so I thought I would pass my solution along.

My errors seem to stem from a old App.Config file and the "in place" upgrade from .Net 4.0 to .Net 4.5.1.

When I started the older project up after upgrading to Framework 4.5.1 I got the TypeInitializationException... right off the bat... not even able to step through one line of code.

After creating a brand new wpf project to test, I found that the newer App.Config file wants the following.

  <configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="YourAppName.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
  </configSections>  

Once I dropped that in, I was in business.

Note that your need might be slightly different. I would create a dummy project, check out the generated App.Config file and see if you have anything else missing.

Hope this helps someone. Happy Coding!

The TypeInitializationException that is thrown as a wrapper around the exception thrown by the class initializer. This class cannot be inherited.

TypeInitializationException is also called static constructors.

Vishal

I have the error of system.typeintialzationException, which is due to when I tried to move the file like:

 File.Move(DestinationFilePath, SourceFilePath)

That error was due to I had swapped the path actually, correct one is:

 File.Move(SourceFilePath, DestinationFilePath)

Had a simular issue getting the same exception. Took some time locating. In my case I had a static utility class with a constructor that threw the exception (wrapping it). So my issue was in the static constructor.

I had this problem. As stated it is probably a static declaration issue. In my case it was because I had a static within a DEBUG clause. That is (in c#)

#if DEBUG
    public static bool DOTHISISINDEBUGONLY = false;
#endif

Everything worked fine until I complied a Release version of the code and after that I got this error - even on old release versions of the code. Once I took the variable out of the DEBUG clause everything returned to normal.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!