容易被忽视,错用的构造函数 .cctor-- 静态构造函数

only_lonely 2010-03-12 12:47:39
加精
.ctor 是大家都知道的

.cctor 却不被人所熟习,也很容易被误用

所谓的的 .cctor 放在C#的语法中,就是静态的构造函数

形如


class A

{

static A() // 这就是一个.cctor构造函数

}


.cctor 与 .ctor之间的异同

1,不能有访问权限标识符 public,private,等等,都不能使用,这与.ctor不同

2,不能有返回值,这与.ctor相同

3,不能有参数,.ctor可以拥有多个参数

4,最多只能有一个,.ctor至少要有一个

5,程序员不能控制调用.cctor的时机,.ctor 从某种意义上说,程序员可以控制它调用的时机

6,程序员无法直接调用.cctor , .ctor 当程序员使用new操作符时,.ctor是一定会被调用的


.cctor 的调用时机 :


在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。(这是MSDN上的原话)

很明显,同一个程序域中.cctor 只会调用一次,而不是像.ctor每次实例化对象都会被调用

.cctor用处

静态构造函数用于初始化任何静态 数据,或用于执行仅需执行一次的特定操作。


举例说明:

以下所有代码 在 windows 7, vs 2005 Release 模式下编译确认,若结果不同,请考虑换成release模式重试





using System;
namespace only_lonely
{
class A
{
static void Main(String[] args)
{

}
}
}


将此段代码编译,然后使用ILDASM查看,方法表如下



.ctor() : void //这是由编译器自动提供的类的实例构造函数

Main():void(string[]) //程序入口点

很显然,程序集中并没有.cctor 的身影,在类没有静态的字段需要初始化时,编译器是不会自动提供.cctor函数的,这又与.ctor不同,无论怎样,.ctor一直存在

修改代码


using System;
namespace only_lonely
{
class A
{

static void Main(String[] args)
{

}

static Int32 i = 0;
}
}


编译此段代码,会有一个警告,但那并不重要的,重要的是用ILDASM查看程序集时,预料中的.cctor,静态构造函数并没有出现!





what happened?

难道推论错误了吗?.cctor并不是用来初始化类的静态字段?

take it easy ,请看一下段代码


using System;
namespace only_lonely
{
class A
{

static void Main(String[] args)
{

}

static Int32 i = 1;
}
}


此段代码与上一段代码的唯一不同就是变更了静态字段i的初始值,接下来,就是见证神奇的时刻

让我们DASM 它,令人吃惊的是,千呼万唤的.cctor终于出现了!



查看.cctor的实现代码,会看到

.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldc.i4.1 //实例化静态的字段 :-)
IL_0001: stsfld int32 only_lonely.A::i
IL_0006: ret
} // end of method A::.cctor

为什么会是这样呢?可能的原因是 Int32 类型的默认值 就是 0,而编译器检测到了这个,所以便优化,不产生.cctor的代码

参考

最后,我们可以自己实现一个.cctor函数,以实现特殊的功能需求

...全文
3594 74 打赏 收藏 转发到动态 举报
写回复
用AI写文章
74 条回复
切换为时间正序
请发表友善的回复…
发表回复
troublemaker_2012 2012-07-19
  • 打赏
  • 举报
回复
这一点对我们有什么影响呢?
有刚需就些静态构造洒,不会为了写而写的
liulangzheli 2010-11-03
  • 打赏
  • 举报
回复
学习。。。。
ZXY900213 2010-09-14
  • 打赏
  • 举报
回复
mark...
only_lonely 2010-03-17
  • 打赏
  • 举报
回复
[Quote=引用 75 楼 sjdev 的回复:]

static Int32 i = 0;会有警告信息的吧.
[/Quote]
是滴,变量i从未被使用~,其他的警告则没有,在.net 2.0下如此,更高版本不清楚
sjdev 2010-03-17
  • 打赏
  • 举报
回复
贿赂斑竹?
sjdev 2010-03-17
  • 打赏
  • 举报
回复
static Int32 i = 0;会有警告信息的吧.
dzc1987 2010-03-16
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分
only_lonely 2010-03-16
  • 打赏
  • 举报
回复
[Quote=引用 71 楼 vrhero 的回复:]

你很细心...但是,MSDN说的很清楚了...

静态构造函数用于初始化任何静态数据,即有任何静态字段却没有显式声明静态构造函数都会导致编译器为类自动添加静态构造函数...

然而不幸地是...C# 2.0编译器在优化时对“只有赋默认值的静态字段”不会自动添加静态构造函数,这在更高版本已被修改,以后你不会看到这种奇怪的事了...

ps:这种编译器的小差异知道就行了,不会有什么影响.……
[/Quote]
大牛指教~收下``,其实那个优化`算是偶然发现``,我以前还不知道有.cctor那回事呢```
vrhero 2010-03-16
  • 打赏
  • 举报
回复
你很细心...但是,MSDN说的很清楚了...

静态构造函数用于初始化任何静态数据,即有任何静态字段却没有显式声明静态构造函数都会导致编译器为类自动添加静态构造函数...

然而不幸地是...C# 2.0编译器在优化时对“只有赋默认值的静态字段”不会自动添加静态构造函数,这在更高版本已被修改,以后你不会看到这种奇怪的事了...

ps:这种编译器的小差异知道就行了,不会有什么影响...什么“忽视”、“错用”搞这么隆重就太孔乙己了...
aboutin 2010-03-15
  • 打赏
  • 举报
回复
学习了............
丰王十 2010-03-15
  • 打赏
  • 举报
回复
整一下跑啊!
zhoudashu 2010-03-14
  • 打赏
  • 举报
回复
是有这个问题呵呵。。。 。。。
lyj1102 2010-03-14
  • 打赏
  • 举报
回复
学习 学习
guyixin 2010-03-14
  • 打赏
  • 举报
回复
学习!!!!!!!!!!!!!!
feng5er 2010-03-14
  • 打赏
  • 举报
回复
学习,很不错
fenghui88 2010-03-13
  • 打赏
  • 举报
回复
借鉴,学习学习
yellowgiutou 2010-03-13
  • 打赏
  • 举报
回复
学习了!
asdsazxqw 2010-03-13
  • 打赏
  • 举报
回复
学习中。。谢谢分享
pan_junbiao 2010-03-13
  • 打赏
  • 举报
回复
懂一点了!!!!!!
shamolidehouzi 2010-03-12
  • 打赏
  • 举报
回复
学习收藏了,谢谢分享啊!!!!!!
加载更多回复(54)

17,740

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧