测试题:静态构造函数执行了几次?为什么?

guoyichao 2010-02-01 05:16:34
以下2段代码,静态构造函数分别被执行了几次?为什么?详细阐述一下你的理由。

代码1:
   class Program
{
static Program()
{
Console.WriteLine("Constructor");
}

static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}

static void Main(string[] args)
{
AppDomain d = AppDomain.CreateDomain("Test");
UnhandledExceptionEventHandler h = Program_UnhandledException;
typeof(AppDomain).GetEvent("UnhandledException").AddEventHandler(d, h);
}
}


代码2:
    class Program
{
static Program()
{
Console.WriteLine("Constructor");
}

static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}

static void Main(string[] args)
{
AppDomain d = AppDomain.CreateDomain("Test");
UnhandledExceptionEventHandler h = Program_UnhandledException;
d.SetData("Test", h);
}
}
...全文
602 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
guoyichao 2010-02-10
  • 打赏
  • 举报
回复
没人知道其中的具体原因?

cuike519 2010-02-02
  • 打赏
  • 举报
回复
这种应用场景比较特殊,可能在某些特殊的情况下会使用到。
soaringbird 2010-02-02
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 danjiewu 的回复:]
引用 35 楼 soaringbird 的回复:
理论上是每个AppDomain各一次,但是不同情况的具体实现上可能有些差别


应该不会有差别的,否则就出问题了。
[/Quote]
楼主的代码,我用.Net 3.5和4编译,结果就不一样。
又如18楼的,注册不同的事件,结果又不一样。
chenchan2009 2010-02-02
  • 打赏
  • 举报
回复
第一次程序执行两次,第二次程序执行一次。
guoyichao 2010-02-02
  • 打赏
  • 举报
回复
目前能确认的是与CER有关,关键是在AppDomain的出错退出处理事件应该都是在CER中进行的,所以会对每个事件委托进行RuntimeHelpers.PrepareDelegate,这是一个clr内部方法其内部是怎么执行的只能靠猜测,从我们使用者角度考虑,如果要通过委托激活目标方法所在类的静态构造函数可用的方法也没几个:
1、直接执行该委托
2、通过反射调用默认构造函数
3、是通过反射调用静态构造函数
4、通过RuntimeHelpers.RunClassConstructor执行委托方法反射对象的类型句柄。
通过测试排除了1、2的可能,而3对于用framework的开发者来说是不可能的(会有异常),也就只有4了,不过这仅仅是猜测,这些代码的行为的确很让遵从书面知识的开发人员困惑。

    class M
{
M()
{
Console.WriteLine("Instance");
}

static M()
{
Console.WriteLine("Static");
}

public static void F()
{
Console.WriteLine("M.F");
}
}

class Program1
{
static void Main(string[] args)
{
Action a = M.F;
RuntimeHelpers.PrepareDelegate(a);
}
}

class Program2
{
static void Main(string[] args)
{
Action a = M.F;
RuntimeHelpers.RunClassConstructor(a.Method.ReflectedType.TypeHandle);
}
}




abaochen 2010-02-02
  • 打赏
  • 举报
回复
静态构造函数用于初始化任何静态数据,或用于执行仅需执行一次的特定操作。在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。
danjiewu 2010-02-02
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 soaringbird 的回复:]
理论上是每个AppDomain各一次,但是不同情况的具体实现上可能有些差别
[/Quote]

应该不会有差别的,否则就出问题了。
soaringbird 2010-02-02
  • 打赏
  • 举报
回复
理论上是每个AppDomain各一次,但是不同情况的具体实现上可能有些差别
danjiewu 2010-02-02
  • 打赏
  • 举报
回复
静态函数在类被第一次调用时触发,如果你没有使用到该类,那么静态函数就不会执行。
至于为什么AddEventHandler(d, h)会调用而SetData不会,那就不清楚了。也许是因为Program_UnhandledException定义在Program中的原因?
mj2243 2010-02-02
  • 打赏
  • 举报
回复
果然高深,学习下
ccsflyjj 2010-02-02
  • 打赏
  • 举报
回复
路过
iamseakingii 2010-02-02
  • 打赏
  • 举报
回复
第一个例子有2个域,每个域各执行了一次静态构造函数
guyehanxinlei 2010-02-02
  • 打赏
  • 举报
回复
一次足够了!
Delta 2010-02-02
  • 打赏
  • 举报
回复
只有一次。而且在第一次创建实例时就开始。也就是在new的时候。之后再实例化对象时,就也不会再重新生成了。
kofkyo 2010-02-02
  • 打赏
  • 举报
回复
不会
phoeni_xin 2010-02-02
  • 打赏
  • 举报
回复
mark
Eleve 2010-02-02
  • 打赏
  • 举报
回复
学习了
guoyichao 2010-02-02
  • 打赏
  • 举报
回复
具体的原因究竟是什么,谁来详细讲解下。
focuswe 2010-02-01
  • 打赏
  • 举报
回复
关注
ilovey4 2010-02-01
  • 打赏
  • 举报
回复
一次
加载更多回复(24)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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