C# 什么是以及如何修复 System.TypeInitializationException 错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18989240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is and how to fix System.TypeInitializationException error?
提问by bTagTiger
private static void Main(string[] args)
{
string str = null;
Logger.InitUserLogWithRotation(); // <--- error occur
...
}
When I build project, it has no error. But When I execute it, it always aborted.
当我构建项目时,它没有错误。但是当我执行它时,它总是中止。
I tried to debug project , but System.TypeInitializationException error occurred at first line.
我试图调试项目,但在第一行发生 System.TypeInitializationException 错误。
I've already tried to googling , yet found no solution.
我已经尝试过谷歌搜索,但没有找到解决方案。
It seems like any variable initialize code is wrong , but can't find it.
似乎任何变量初始化代码都是错误的,但找不到它。
Please help me. I'm new to C#.
请帮我。我是 C# 的新手。
Thanks.
谢谢。
※ Here is Logger Class Code
※ 这是记录器类代码
public class Logger
{
private static int HDLOG_PRIORITY_DEBUG = 4;
private static int HDLOG_PRIORITY_ERROR = 1;
private static int HDLOG_PRIORITY_FATAL = 0;
private static int HDLOG_PRIORITY_INFO = 3;
private static int HDLOG_PRIORITY_WARNING = 2;
public static int LOG_LEVEL_DEBUG = 4;
public static int LOG_LEVEL_ERROR = 2;
public static int LOG_LEVEL_FATAL = 1;
public static int LOG_LEVEL_INFO = 5;
public static int LOG_LEVEL_WARNING = 3;
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);
private static bool s_consoleLogging = false;
private static FileStream s_fileStream;
public static HdLoggerCallback s_HdLoggerCallback;
private static string s_logDir = null;
private static string s_logFileName = "XXXX";
private static string s_logFilePath = null;
public static int s_logFileSize = 0xa00000;
private static bool s_loggerInited = false;
private static string s_logLevels = null;
private static int s_logRotationTime = 0x7530;
private static string s_logStringDebug = "DEBUG";
private static string s_logStringError = "ERROR";
private static string s_logStringFatal = "FATAL";
private static string s_logStringInfo = "INFO";
private static string s_logStringWarning = "WARNING";
private static int s_processId = -1;
private static string s_processName = "Unknown";
private static object s_sync = new object();
public static int s_totalLogFileNum = 5;
private static TextWriter writer = Console.Error;
private static void Close()
{
if (!s_consoleLogging)
{
writer.Close();
s_fileStream.Dispose();
writer.Dispose();
}
}
public static void Debug(string msg)
{
Debug("{0}", new object[] { msg });
}
public static void Debug(string fmt, params object[] args)
{
Print(LOG_LEVEL_DEBUG, s_processName, fmt, args);
}
private static void DoLogRotation()
{
Label_0000:
Thread.Sleep(s_logRotationTime);
try
{
lock (s_sync)
{
FileInfo info = new FileInfo(s_logFilePath);
if (info.Length >= s_logFileSize)
{
string destFileName = s_logFilePath + ".1";
string path = s_logFilePath + "." + s_totalLogFileNum;
if (File.Exists(path))
{
File.Delete(path);
}
for (int i = s_totalLogFileNum - 1; i >= 1; i--)
{
string str3 = s_logFilePath + "." + i;
string str4 = s_logFilePath + "." + (i + 1);
if (File.Exists(str3))
{
File.Move(str3, str4);
}
}
File.Move(s_logFilePath, destFileName);
}
}
goto Label_0000;
}
catch (Exception)
{
goto Label_0000;
}
}
public static void Error(string msg)
{
Error("{0}", new object[] { msg });
}
public static void Error(string fmt, params object[] args)
{
Print(LOG_LEVEL_ERROR, s_processName, fmt, args);
}
public static void Fatal(string msg)
{
Fatal("{0}", new object[] { msg });
}
public static void Fatal(string fmt, params object[] args)
{
Print(LOG_LEVEL_FATAL, s_processName, fmt, args);
}
private static string GetLogDir(bool userSpecificLog)
{
string str;
if (s_logDir != null)
{
return s_logDir;
}
try
{
if (userSpecificLog)
{
str = Path.Combine(s_bstUserDataDir, "Logs");
}
else
{
str = (string) Registry.LocalMachine.OpenSubKey(@"Software\XXXX").GetValue("LogDir");
}
}
catch (Exception)
{
str = Path.Combine(s_bstUserDataDir, "Logs");
}
s_logDir = str;
return str;
}
private static string GetPrefix(string tag, string logLevel)
{
int managedThreadId = Thread.CurrentThread.ManagedThreadId;
DateTime now = DateTime.Now;
return string.Format("{0:D4}-{1:D2}-{2:D2} {3:D2}:{4:D2}:{5:D2}.{6:D3} {7}:{8:X8} ({9}). {10}: ", new object[] { now.Year, now.Month, now.Day, now.Hour, now.Minute, now.Second, now.Millisecond, s_processId, managedThreadId, tag, logLevel });
}
public static TextWriter GetWriter()
{
return new Writer(delegate (string msg) {
Print(msg);
});
}
private static void HdLogger(int prio, uint tid, string tag, string msg)
{
int level = 0;
if (prio == HDLOG_PRIORITY_FATAL)
{
level = LOG_LEVEL_FATAL;
}
else if (prio == HDLOG_PRIORITY_ERROR)
{
level = LOG_LEVEL_ERROR;
}
else if (prio == HDLOG_PRIORITY_WARNING)
{
level = LOG_LEVEL_WARNING;
}
else if (prio == HDLOG_PRIORITY_INFO)
{
level = LOG_LEVEL_INFO;
}
else if (prio == HDLOG_PRIORITY_DEBUG)
{
level = LOG_LEVEL_DEBUG;
}
Print(level, tag, "{0:X8}: {1}", new object[] { tid, msg });
}
public static void Info(string msg)
{
Info("{0}", new object[] { msg });
}
public static void Info(string fmt, params object[] args)
{
Print(LOG_LEVEL_INFO, s_processName, fmt, args);
}
public static void InitConsoleLog()
{
InitLog("-", true, false);
}
public static void InitLog(string logFileName, bool userSpecificLog, bool doLogRotation)
{
s_loggerInited = true;
s_HdLoggerCallback = new HdLoggerCallback(Logger.HdLogger);
s_processId = Process.GetCurrentProcess().Id;
s_processName = Process.GetCurrentProcess().ProcessName;
if (logFileName == "-")
{
writer = Console.Error;
s_consoleLogging = true;
}
else
{
if (logFileName == null)
{
logFileName = s_logFileName;
}
if (userSpecificLog)
{
logFileName = logFileName + "Users";
}
string logDir = GetLogDir(userSpecificLog);
string str2 = string.Format(@"{0}\{1}.log", logDir, logFileName);
if (!Directory.Exists(logDir))
{
Directory.CreateDirectory(logDir);
}
s_logFilePath = str2;
LogLevelsInit();
lock (s_sync)
{
Open();
}
if (doLogRotation)
{
new Thread(() => DoLogRotation()) { IsBackground = true }.Start();
}
}
}
public static void InitSystemLog()
{
InitLog(null, false, false);
}
public static void InitSystemLogWithRotation()
{
InitLog(null, false, true);
}
public static void InitUserLog()
{
InitLog(null, true, false);
}
public static void InitUserLogWithRotation()
{
InitLog(null, true, true);
}
private static bool IsLogLevelEnabled(string tag, string level)
{
if (s_logLevels == null)
{
return false;
}
return (s_logLevels.StartsWith("ALL") || s_logLevels.Contains((tag + ":" + level).ToUpper()));
}
private static void LogLevelsInit()
{
string name = @"Software\XXXX\Config";
try
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(name))
{
s_logLevels = (string) key.GetValue("DebugLogs");
}
}
catch (Exception)
{
return;
}
if (s_logLevels != null)
{
s_logLevels = s_logLevels.ToUpper();
}
}
private static void Open()
{
if (!s_consoleLogging)
{
if (!s_loggerInited)
{
InitLog("-", false, false);
s_loggerInited = true;
}
else
{
s_fileStream = new FileStream(s_logFilePath, FileMode.Append, FileAccess.Write, FileShare.Delete | FileShare.ReadWrite);
writer = new StreamWriter(s_fileStream, Encoding.UTF8);
}
}
}
public static void Print(string msg)
{
Print("{0}", new object[] { msg });
}
public static void Print(string fmt, params object[] args)
{
Print(LOG_LEVEL_INFO, s_processName, fmt, args);
}
public static void Print(int level, string tag, string fmt, params object[] args)
{
string str = "UNKNOWN";
if (level == LOG_LEVEL_FATAL)
{
str = s_logStringFatal;
}
else if (level == LOG_LEVEL_ERROR)
{
str = s_logStringError;
}
else if (level == LOG_LEVEL_WARNING)
{
str = s_logStringWarning;
}
else if (level == LOG_LEVEL_INFO)
{
str = s_logStringInfo;
}
else if (level == LOG_LEVEL_DEBUG)
{
str = s_logStringDebug;
}
if ((level != LOG_LEVEL_DEBUG) || IsLogLevelEnabled(tag, str))
{
lock (s_sync)
{
Open();
writer.WriteLine(GetPrefix(tag, str) + fmt, args);
writer.Flush();
Close();
}
}
}
public static void SetLogDir(string logDir)
{
s_logDir = logDir;
}
public static void Warning(string msg)
{
Warning("{0}", new object[] { msg });
}
public static void Warning(string fmt, params object[] args)
{
Print(LOG_LEVEL_WARNING, s_processName, fmt, args);
}
public delegate void HdLoggerCallback(int prio, uint tid, string tag, string msg);
public class Writer : TextWriter
{
private WriteFunc writeFunc;
public Writer(WriteFunc writeFunc)
{
this.writeFunc = writeFunc;
}
public override void WriteLine(string msg)
{
this.writeFunc(msg);
}
public override void WriteLine(string fmt, object obj)
{
this.writeFunc(string.Format(fmt, obj));
}
public override void WriteLine(string fmt, object[] objs)
{
this.writeFunc(string.Format(fmt, objs));
}
public override System.Text.Encoding Encoding
{
get
{
return System.Text.Encoding.UTF8;
}
}
public delegate void WriteFunc(string msg);
}
}
采纳答案by olydis
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
.
每当TypeInitializationException
被抛出,检查你是指为在抛出异常的语句中的第一次所有类型的初始化逻辑-你的情况:Logger
。
Initialization logic includes: the type's static constructor (which - if I didn't miss it - you do nothave for Logger
) and field initialization.
初始化逻辑包括:类型的静态构造函数(它 - 如果我没有错过它 - 你没有for Logger
)和字段初始化。
Field initialization is pretty much "uncritical" in Logger
except for the following lines:
Logger
除了以下几行之外,字段初始化几乎是“不重要的” :
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 exactorder you wrote them - so put s_commonAppData
up by at least two lines ;)
s_commonAppData
是null
在Path.Combine(s_commonAppData, "XXXX");
被调用的地方。就我而言,这些初始化按照您编写它们的确切顺序发生-因此s_commonAppData
至少要放置两行;)
回答by dasblinkenlight
System.TypeInitializationException
happens when the code that gets executed during the process of loading the type throws an exception.
System.TypeInitializationException
当在加载类型的过程中执行的代码抛出异常时发生。
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
.
当 .NET 加载该类型时,它必须在您第一次使用该类型之前准备其所有静态字段。有时,初始化需要运行代码。当该代码失败时,您将获得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.
请注意,s_bstCommonAppData
取决于s_commonAppData
,但它是在其依赖项之前声明的。因此, 的值s_commonAppData
是null
在Path.Combine
调用 时,导致ArgumentNullException
。这同样适用于s_bstUserDataDir
和s_bstCommonAppData
:它们以相反的顺序初始化的期望的顺序声明。
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");
回答by cdhowie
These lines are your problem (or at least oneof 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.
您在其他静态成员的初始值设定项中引用了一些静态成员。这是一个坏主意,因为编译器不知道初始化它们的顺序。结果是在 的初始化过程中s_bstCommonAppData
,依赖字段s_commonAppData
尚未初始化,因此您正在调用Path.Combine(null, "XXXX")
并且此方法不接受空参数。
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");
}
回答by Hitesh Modha
The TypeInitializationException
that is thrown as a wrapper around the exception thrown by the class initializer. This class cannot be inherited.
该TypeInitializationException
所引发由类初始抛出的异常周围的包装。这个类不能被继承。
TypeInitializationException is also called static constructors.
TypeInitializationException 也称为静态构造函数。
回答by Vishal
I have the error of system.typeintialzationException, which is due to when I tried to move the file like:
我有 system.typeintialzationException 错误,这是由于当我尝试移动文件时,例如:
File.Move(DestinationFilePath, SourceFilePath)
That error was due to I had swapped the path actually, correct one is:
该错误是由于我实际上交换了路径,正确的一个是:
File.Move(SourceFilePath, DestinationFilePath)
回答by pStan
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.
我的错误似乎源于旧的 App.Config 文件和从 .Net 4.0 到 .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.
当我在升级到 Framework 4.5.1 后启动旧项目时,我得到了 TypeInitializationException ......立即......甚至无法单步执行一行代码。
After creating a brand new wpf project to test, I found that the newer App.Config file wants the following.
创建了一个全新的wpf项目进行测试后,发现较新的App.Config文件需要如下内容。
<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.
请注意,您的需求可能略有不同。我会创建一个虚拟项目,查看生成的 App.Config 文件,看看是否还有其他遗漏。
Hope this helps someone. Happy Coding!
希望这可以帮助某人。快乐编码!
回答by 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.
System.TypeInitializationException
由于我的 .NET framework 4 项目的 app.config 中的不同错误,我遇到了。感谢 pStan 让我查看 app.config。我的 configSections 已正确定义。但是,其中一个部分中的未定义元素导致抛出异常。
Bottom line is that problems in the app.config can generated this very misleading TypeInitializationException
.
底线是 app.config 中的问题会产生这种非常误导的情况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.
ConfigurationErrorsException
通过等待访问配置值直到您在方法中而不是在代码的类级别,app.config 中的相同错误可以生成更有意义的错误。
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;
}
}
}
回答by pete515
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#)
我有这个问题。如前所述,这可能是一个静态声明问题。就我而言,这是因为我在 DEBUG 子句中有一个静态。那是(在 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.
一切正常,直到我编译了代码的发布版本,然后我收到了这个错误 - 即使在代码的旧发布版本上也是如此。一旦我从 DEBUG 子句中取出变量,一切都恢复正常。
回答by ShivanandSK
i. Please check the InnerException
property of the TypeInitializationException
一世。请检查InnerException
物业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
ii. 此外,这可能是由于程序集的运行时版本之间不匹配而发生的。请验证主程序集(调用应用程序)和引用程序集的运行时版本
回答by Acorax
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.
有一个类似的问题得到相同的异常。花了一些时间定位。在我的例子中,我有一个带有构造函数的静态实用程序类,该类抛出异常(包装它)。所以我的问题出在静态构造函数中。