类型初始值设定项引发异常

摘要:
-早上打开VS编译器时,突然出现运行时错误“类型初始化器抛出异常”。过去,在编译时,我总是忘记打开服务器,这经常导致MQ访问失败。昨天结束时,我重构了类的单例模式,并使用了静态初始化方法。
-上午打开VS编译程序的时候,突然出现了这个运行时错误“类型初始值设定项引发异常”。昨天还没有这个错误呢,今天就突然出现,搞得我一头雾水。上网搜了一下,发现有很多人遇到了这个问题。经过一番折腾解决了这个问题后,发现很多人都没有意识到其症结所在,于是写这个随笔,给大家点启发,也给自己做个备忘。

症状描述:
我的程序需要连接一台MQ服务器(其实就是个台式机,每天下班关机),如果服务器没有开,程序就会抛出异常。以前编译时老是忘开服务器,经常会出现MQ访问失败的异常。这次我原本以为也是这个异常,没想到出来的是“类型初始值设定项引发异常”。
今天的错误为什么会和以往不一样呢?昨天临下班时,把一个类的单件模式做了重构,使用了静态初始化方法。代码如下:
类型初始值设定项引发异常第1张private static readonly WorkerManager instance = new WorkerManager();
类型初始值设定项引发异常第2张类型初始值设定项引发异常第3张
static WorkerManager() 类型初始值设定项引发异常第4张{ }
类型初始值设定项引发异常第1张
private WorkerManager()
类型初始值设定项引发异常第2张类型初始值设定项引发异常第3张
类型初始值设定项引发异常第4张{
类型初始值设定项引发异常第9张    Initialize();
类型初始值设定项引发异常第10张}

类型初始值设定项引发异常第1张
public static WorkerManager Instance
类型初始值设定项引发异常第2张类型初始值设定项引发异常第3张
类型初始值设定项引发异常第4张{
类型初始值设定项引发异常第15张类型初始值设定项引发异常第16张    
get 类型初始值设定项引发异常第4张return instance; }
类型初始值设定项引发异常第10张}
访问MQ的语句在Initialize方法里,问题就应该出现在这里了。

解决方法:
当然,把MQ服务器打开问题就解决了,但是究竟为什么会出现“类型初始值设定项引发异常”呢?
原来类的静态成员在初始化时如果出现异常,访问类的其它静态成员或对该类进行初始化都会抛出这个异常。请看下面的代码:
类型初始值设定项引发异常第1张    public class Test
类型初始值设定项引发异常第2张类型初始值设定项引发异常第3张    
类型初始值设定项引发异常第4张{
类型初始值设定项引发异常第9张        
public static Foo Test1 = new Foo();
类型初始值设定项引发异常第9张        
public static string Test2 = "Test2";
类型初始值设定项引发异常第9张        
public string Test3 = "Test3";
类型初始值设定项引发异常第15张类型初始值设定项引发异常第16张        
public Test() 类型初始值设定项引发异常第4张{ }
类型初始值设定项引发异常第10张    }

类型初始值设定项引发异常第1张
类型初始值设定项引发异常第1张    
public class Foo
类型初始值设定项引发异常第2张类型初始值设定项引发异常第3张    
类型初始值设定项引发异常第4张{
类型初始值设定项引发异常第9张        
public Foo()
类型初始值设定项引发异常第15张类型初始值设定项引发异常第16张        
类型初始值设定项引发异常第4张{
类型初始值设定项引发异常第9张            
throw new Exception();
类型初始值设定项引发异常第40张        }

类型初始值设定项引发异常第10张    }

在访问Test.Test2以及new Test()时都会抛出这个异常。我的代码中,由于Initialize()出现异常,instance实例化失败,所以访问Instance时就抛出了这个异常。

总结:

TypeInitializationExeption在MSND中的描述为:当类初始值设定项不能初始化类型时,将创建 TypeInitializationException 并向其传递由该类型的类初始值设定项引发的异常引用。

我们知道,类型初始化或者访问类型的静态成员时,都会对类中的其他静态成员进行初始化,并执行静态构造函数(如果有的话)。在这些过程中如果任一环节出现例如下面的代码:

类型初始值设定项引发异常第42张类型初始值设定项引发异常第43张Code
    class ClassHelper
    {
        
public static string Field = Do("Initial the static field");
        
public static string StaticString = "Initaial static string";
        
public string NonStaticString = "Initial non static string";
        
public ClassHelper()
        {
            NonStaticString 
= "Change non static string in instance constructor";
            StaticString 
= "Change static string in instance constructor";
        }
        
public static string Do(string field)
        {
            Console.WriteLine(field);
            
throw new Exception();
            
return field;
        }
    }

    

那么产生TypeInitializationException的情况就包含以下几种:

1. 访问类的某一静态成员,而其他静态成员的初始化(或静态构造函数中)产生异常。例如访问ClassHelper.StaticString,由于静态成员Field的初始化产生异常,因此调用ClassHelper.StaticString会抛出TypeInitializationException。

2. 访问类的某一静态成员,该静态成员的初始化(或静态构造函数中)产生异常。例如访问ClassHelper.Field。

3. 对该类进行初始化,而类中的某个静态成员初始化(或静态构造函数中)产生异常。例如ClassHelper helper = new ClassHelper()。

免责声明:文章转载自《类型初始值设定项引发异常》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Docker ComposeQt Creator- Beautifier插件代码格式化,使用 Clang Code Model下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java Selenium3 WebDriver启动火狐、Chrome、IE,Edge浏览器的方法(一)

selenium3和selenium2没有太大的区别,就是精简了一些不用的东西,对浏览器的支持更好了,比如对高版本的浏览器(FireFox,Chrome,Edge等)可以完美的支持,不用受限于版本的问题 下面总结一下启动常用浏览器的方法 前提 安装好java的环境配置 新建一个maven工程 在maven的pom文件加入selenium的依赖包(版本可根...

ES6中class的使用+继承

一.Class 介绍+基本语法(1).介绍通过class关键字,可以定义类。基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。 (2).Class 的基本语法 //definedClasses.js //定义类 class Person{...

AS86 汇编器

内核编程语言和环境 语言编译过程就是把人类理解的高级语言转换成计算机硬件能理解和执行的二进制机器指令的过程。这种转换过程通常会产生一些效率不是很高的代码。所以一些对运行效率要求高或者性能影响较大的部分代码就会直接使用汇编语言来编写。或者对高级语言编译产生的汇编程序在进行人工修改或优化。 AS86汇编器 Linux0.1x系统中使用了两种汇编器,一种是能产...

经典MFC界面和Ribbon界面框架对比(单文档为例)

IDE为:VS2008+SP1 A为经典MFC单文档界面: B为Ribbon风格的MFC单文档界面: 在生成A和B的基础框架代码之后,通过对比工具,发现这两种不同风格的界面主要在MainFrame类中存在一些差异。 应用程序类(CXXXApp)的InitInstance()函数中,B风格在调用InitContextMenuManager()之后,执行了...

【python系统学习13】类(class)与对象(object)

目录: 类(class)和实例 类 实例 小测试 对象(object) 属性和方法 类的创建 伪代码 示例代码 属性(attribute) 方法(method) 类的实例化 实例对象调用类属性和方法 调用类的属性 调用类的方法 示例代码 特殊参数:self 1、代指实例化对象的作用 2、定义方法必传self 3、调用方法传参时sel...

用Gitolite搭建服务器上的Git

使用git作为版本控制工具,确实非常流行且好用,常用的git代码服务器有Github还是国内的Gitcafe和OSC都是很不错,可以免费存放一些开源的项目代码,对于私人项目,则需要支付一定的费用。同时对于代码安全隐私的考虑,有时需要搭建自己的私有git服务器,官方wiki有介绍,这里在整理一遍自己的搭建过程,供之后参看。 安装基础依赖包 1 # yum...