`
k_lb
  • 浏览: 798909 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论
  • kitleer: 据我所知,国内有款ETL调度监控工具TaskCTL,支持ket ...
    kettle调度

静态构造函数范例

 
阅读更多

很多C#和ASP.NET相关工作都可能遇到这样一道题。很简单,但是考察的知识点很多。

class A
{
public static int X;

static A()
{
X = B.Y + 1;
}

}

class B
{
public static int Y = A.X + 1;

static B()
{

}

static void Main()
{
Console.WriteLine("X = {0}, Y = {1}", A.X, B.Y);
Console.Read();
}
}

写出最后输出结果。

结果是: X = 1, Y = 2

================================================================

[反复阅读,摘自《Professional C# 2005 with .NET 3.0》第五版P87]

静态构造函数
C#的一个新特征是也可以给类编写无参数的静态构造函数。这种构造函数只执行一次,而前面的构造函数是实例构造函数,只要创建类的对象,它都会执行。……
编写静态构造函数的一个原因是,类有一些静态字段或属性,需要在第一次使用类之前,从外部源中初始化这些静态字段和属性。
.NET运行库……。但是,可以确保静态构造函数至多运行一次,即在代码引用类之前执行。在C#中,静态构造函数通常在第一次调用类的成员之前执行
注意,静态构造函数没有访问修饰符,其他C#代码从来不调用它,但在加载类时,总是有.NET运行库调用它,……。同样,静态构造函数不能带任何参数一个类也只能有一个静态构造函数。很显然,静态构造函数只能访问类的静态成员,不能访问实例成员。
注意,无参数的实例构造函数可以在类中与静态构造函数安全共存。尽管参数列表是相同的,但这并不矛盾,因为静态构造函数是在加载类时执行,而实例构造函数是在创建实例时执行,所以构造函数的执行不会有冲突。
(个人觉得重要的内容,已用红色字体标记。仅供参考。)

===============================================================

再次明确一下特点

一个类的静态(static)构造函数在给定的应用程序域中仅执行一次。静态构造函数由在应用程序域的下列事件的首次发生时触发:
(1)该类的实例被创建。
(2)任何一个static成员被引用
(3)如果类包含执行入口Main方法,此类的static构造函数在Main方法被调用之前执行。
(4)如果类包含任何static成员,则这些static成员在static构造函数之前进行初始化。
(5)如果类包含任何static方法,则这些static方法在static构造函数之后进行初始化。
(6)对于存在多个static成员,他们的初始化将按照文本顺序进行,不会因为调用顺序而改变。

===============================================================

上面简单示例的分析

根据第(3)点,class B中有Main方法入口,所以先调用static B(),但并没有赋值,只作默认初始化,即 Y = 0。
然后调用A.X,那么就调用class A中的静态构造函数 static A()进行初始化。所以,X = B.Y + 1 = 1。
最后,class B 中Console输出的语句又调用B.Y ,class B中 Y = A.X + 1,A.X已被赋值为1,那么 Y = 1 + 1 = 2。

故,输出结果为 X = 1, Y = 2

--------------------------------------------------------

也有朋友这样解释。个人觉得这种解释是对的,上面的便于理解。关键在于最初调用static B()时对Y的初始化问题。

“现在看看上面的应用程序,Class B中有个Main执行入口,所以B首先得到初始化,顺序是static成员Y->static构造函数。在初始化Y时,引用了A.X,编译器又开始初始化Class A(注意这时Class B的初始化并没有完成),顺序也是static成员X->static构造函数。Class A中X在定义的时候没有被赋予初始值(在定义static变量时,尽量赋予初始值),编译器会默认赋予值0(int型)。然后再执行static的构造函数,由于Class B的初始化这时还没有完成,所以B.Y的值在这时被编译器赋予默认值0,所以在A的static的构造函数执行完后,X的值变为1,然后返回B继续完成初始化,得到Y的值为2。最后执行Main,输出A.X和B.Y的值。”

===============================================================

(以下附加说明摘自网络)

附加说明:
/// 静态构造函数是实现对一个类进行初始化的方法成员。
/// 它一般用于对静态数据的初始化。
/// 静态构造函数只能是私有的,静态构造函数不能有修饰符
/// 静态构造函数不能有参数,不能有修饰符而且不能被调用,
/// 当类被第一次使用的时候,类的静态构造函数自动被调用。
/// 静态构造函数只能对静态数据成员进行初始化,而不能对非静态数据成员进行初始化。
/// 静态方法不能接收到this指针。
/// 因此他们不能直接访问类里的任何实例化数据
/// 静态构造函数在IL中表示为cctor(class contructor)

分享到:
评论

相关推荐

    Google_Maps_API_说明.doc

     构造函数  方法  配置  控件处理  状态  标注  信息浮窗  事件 o GMarker  构造函数  方法 o GPolyline  构造函数 o GIcon  构造函数  属性 o Google Earthvent  ...

    Google Maps API 中文说明文档

    GIcon 构造函数 属性 GEvent 静态方法 GXmlHttp 静态方法 GXml 静态方法 GXslt 静态方法 方法 GPoint 构造函数 属性 GSize 构造函数 属性...

    零起点学通C++多媒体范例教学代码

    11.10.2 通过构造函数将变量转换为一个对象的成员变量 11.10.3 通过operator关键字进行转换 11.11什么可以重载,什么不可以重载 第12章 继承 12.1 什么是继承和派生 12.1.1 复杂的继承和派生 12.1.2 继承和派生如何...

    零起点学通C++学习_多媒体范例教学代码

    11.10.2 通过构造函数将变量转换为一个对象的成员变量 11.10.3 通过operator关键字进行转换 11.11什么可以重载,什么不可以重载 第12章 继承 12.1 什么是继承和派生 12.1.1 复杂的继承和派生 12.1.2 继承和...

    中科院 C++PPT及代码

    C++课件及范例代码(中科院):对象与类,构造函数与析构函数,堆与拷贝构造函数,静态数据成员与静态成员函数等内容。中科院研究生院教学用课件以及范例代码,老师讲的很深刻,每次上课人爆满。值得下载!

    -C++参考大全(第四版) (2010 年度畅销榜

    第二部分详细介绍了C++本身的特性,如类和对象、构造函数、析构函数和模板等;第三部分描述了标准函数库;第四部分讨论了标准类库,包括STL(标准模板库);第五部分显示了两个应用C++和面向对象编程的实际例子。 本书...

    AJAX 源码范例

    07/7.2.3.html 获取cookie的值范例 07/7.2.4.html 给cookie设置终止日期范例 07/7.2.5.html 删除cookie范例 07/7.2.8.html 综合示例:构造通用的cookie处理函数 07/7.4.2.html 使用定时器...

    quilt:拼接Mapbox静态图块

    然后,您可以使用构造函数返回通过在该位置将图块拼接在一起以生成一种或多种Mapbox样式而生成的图像。 使用范例 const { makeGetQuilt } = require ( '@mapbox/quilt' ) ; const getTileQuilt = makeGetQuilt ( ...

    java范例开发大全(pdf&源码)

    实例188 使用取整函数 317 11.2 Random类的使用 318 实例189 随机数 319 实例190 验证码 322 11.3 Date类和Calendar类 324 实例191 使用Date类获取系统的当前时间 324 实例192 使用DateFormat类获取系统的当前时间 ...

    深入浅出MFC-简体版(2)PDF

    C++程序的生与死:兼谈构造函数与解构函数 四种不同的对象生存方式(in stack、in heap、global、local static) 执行期类型信息(RTTI) 动态生成(Dynamic Creation) 异常处理(Exception Handling) Template ...

    vim-react-snippets:在React中开发有用的代码片段(Javascript和Typescript)

    vim-react-snippets 用于...Javascript范例打字稿示例钩子的例子目录 React类导出React类组件React Class构造函数静态属性类型静态默认道具React类函数(箭头绑定类函数) 功能组件(JavaScript) 功能组件导出简单功

    Effective C++

    条款11:为需要动态分配内存的类声明一个拷贝构造函数和一个赋值函数 条款12:尽量使用初始化而不要在构造函数里赋值 条款13:初始化列表中成员列出顺序和它们在类中的声明顺序相同 条款14:确定基类有虚析构函数 条款15...

    java范例开发大全源代码

     实例188 使用取整函数 317  11.2 Random类的使用 318  实例189 随机数 319  实例190 验证码 322  11.3 Date类和Calendar类 324  实例191 使用Date类获取系统的当前时间 324  实例192 使用...

    java范例开发大全

    实例188 使用取整函数 317 11.2 Random类的使用 318 实例189 随机数 319 实例190 验证码 322 11.3 Date类和Calendar类 324 实例191 使用Date类获取系统的当前时间 324 实例192 使用DateFormat类获取系统的当前时间 ...

    Java范例开发大全 (源程序)

     实例188 使用取整函数 317  11.2 Random类的使用 318  实例189 随机数 319  实例190 验证码 322  11.3 Date类和Calendar类 324  实例191 使用Date类获取系统的当前时间 324  实例192 使用DateFormat类...

    Java范例开发大全(全书源程序)

    Java范例开发大全(全书源程序),目录如下: 第1篇 Java编程基础 第1章 Java开发环境的搭建(教学视频:9分钟) 2 1.1 理解Java 2 1.2 搭建Java所需环境 3 1.2.1 下载JDK 3 1.2.2 安装JDK 4 1.2.3 配置环境...

    《深度探索C++对象模型》(Stanley B·Lippman[美] 著,侯捷 译)

    第2章 构造函数语意学(The Semantics of constructors) 2.1 Default Constructor的建构操作 “带有Default Constructor”的Member Class Object “带有Default Constructor”的Base Class “带有一个Virual ...

    深入浅出MFC【侯捷】

    C++程序的生与死:兼谈构造函数与解构函数 四种不同的对象生存方式(in stack、in heap、global、local static) 执行期类型信息(RTTI) 动态生成(Dynamic Creation) 异常处理(Exception Handling) Template ...

    深入浅出MFC 2e

    C++程序的生与死:兼谈构造函数与解构函数 四种不同的对象生存方式(in stack、in heap、global、local static) 执行期类型信息(RTTI) 动态生成(Dynamic Creation) 异常处理(Exception Handling) Template ...

    侯捷- -深入浅出MFC

    C++程序的生与死:兼谈构造函数与解构函数 四种不同的对象生存方式(in stack、in heap、global、local static) 执行期类型信息(RTTI) 动态生成(Dynamic Creation) 异常处理(Exception Handling) Template ...

Global site tag (gtag.js) - Google Analytics