发现一段很诡异的C#代码,见识了静态构造函数这种奇怪的东西:

  1. using System;
  2. namespace StaticTest
  3. {
  4. class A
  5. {
  6. public static int X;
  7. static A()
  8. {
  9. X = B.Y + 1;
  10. }
  11. }
  12. class B
  13. {
  14. public static int Y = A.X + 1;
  15. static B()
  16. {
  17. }
  18. static void Main()
  19. {
  20. Console.WriteLine("X={0}, Y={1}", A.X, B.Y);
  21. }
  22. }
  23. }

先补习下吧:

  1、静态构造函数既没有访问修饰符,也没有参数。因为是.NET调用的,所以像public和private等修饰符就没有意义了。 
   
  2、是在创建第一个类实例或任何静态成员被引用时,.NET将自动调用静态构造函数来初始化类,也就是说我们无法直接调用静态构造函数,也就无法控制什么时候执行静态构造函数了。

  3、一个类只能有一个静态构造函数。

  4、无参数的构造函数可以与静态构造函数共存。尽管参数列表相同,但一个属于类,一个属于实例,所以不会冲突。

  5、最多只运行一次。

  6、静态构造函数不可以被继承。

  7、如果没有写静态构造函数,而类中包含带有初始值设定的静态成员,那么编译器会自动生成默认的静态构造函数。

好,复习完毕,哪位同学回答下上面程序的输出结果是多少?

还是搞不明白吧:) 唔,你明白了?他没明白,我也没明白……

class A静态构造函数中的B.Y好像很奇怪,貌似要确定A.X的值,得先确定B.Y的值,而B.Y的值在B中却是由A.X来确定的,那A.X的值……啊,要疯掉了……应该是多少呢?不敢确定了吧,交给编译器来运行看看吧~~ 
结果如下:

  1. X=1, Y=2

修改下代码,看看内部到底怎么运行的:

  1. using System;
  2. namespace StaticTest
  3. {
  4. class A
  5. {
  6. public static int X;
  7. static A()
  8. {
  9. Console.WriteLine("calling A");
  10. Console.WriteLine(B.Y);
  11. X = B.Y + 1;
  12. }
  13. }
  14. class B
  15. {
  16. public static int Y = A.X + 1;
  17. static B()
  18. {
  19. Console.WriteLine("calling B");
  20. Console.WriteLine(Y);
  21. }
  22. static void Main()
  23. {
  24. Console.WriteLine("X={0}, Y={1}", A.X, B.Y);
  25. }
  26. }
  27. }

执行结果如下:

  1. calling A
  2. 0
  3. calling B
  4. 2
  5. X=1, Y=2

看到这个结果,对C#更加迷惑了。类A中静态构造函数调用得到的B.Y,居然是0。这是什么道理?难道这个时候B还没出生,但是B.Y已经出生了?不管了,先接受了吧,以后玩C#还是小心点了。哪位神仙指点指点迷津啊?

说说C#静态变量的诡异与恶心的更多相关文章

  1. PHP 面向对象编程和设计模式 (2/5) - 静态变量、属性和方法及延迟绑定

    PHP高级程序设计 学习笔记 2014.06.10 Static(静态)关键字用来定义静态方法和属性,static 也可用于定义静态变量以及后期静态绑定. 1.静态变量 static variable ...

  2. [转]Android静态变量的生命周期

    原文地址:https://my.oschina.net/jerikc/blog/137207 Android是用Java开发,其静态变量的生命周期遵守Java的设计.我们知道静态变量是在类被load的 ...

  3. QT,静态变量要记得初始化

    //DbUtil.h #ifndef DBUTIL_H #define DBUTIL_H using namespace std; QString md5Encode(QString passwd); ...

  4. .NET静态变量与静态方法并发的问题

    我们知道,静态变量与静态方法都是在程序编译的时候就定义好了的,并且不会存在多个副本.所以对于静态变量来说,一旦修改了就会影响全局. 因此,静态变量是存在并发性问题的,所以当我们在操作静态变量的时候需要 ...

  5. JAVA的静态变量、静态方法、静态类

    静态变量和静态方法都属于静态对象,它与非静态对象的差别需要做个说明. (1)Java静态对象和非静态对象有什么区别? 比对如下: 静态对象                                ...

  6. 关于C#静态变量初始化问题

    关于这个静态变量,平时自己没有太认真的去认识.最近调项目的bug,让我重新认识了静态变量的特点. 其实,我们一直都在说:静态变量只在类第一次初始化的时候进行初始化,以后都不初始化. 很简单的一句话,但 ...

  7. android 尽量不要使用static静态变量

    使用静态static静态变量潜在性问题: 1.占用内存,并且内存一般不会释放: 2.在系统不够内存情况下会自动回收静态内存,这样就会引起访问全局静态错误. 3.不能将activity作为static静 ...

  8. Java代码执行顺序(静态变量,非静态变量,静态代码块,代码块,构造函数)加载顺序

    //据说这是一道阿里巴巴面试题,先以这道题为例分析下 public class Text { public static int k = 0; public static Text t1 = new ...

  9. Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

    直接上代码: 代码1: public class ConstroctTest { private static ConstroctTest test = new ConstroctTest(); // ...

随机推荐

  1. [转]inux之touch命令

    转自:http://www.2cto.com/os/201309/242518.html Linux学习之touch命令   Linux的touch命令一般用来更改文档或目录的日期时间,包括存取时间和 ...

  2. 《DevOps故障排除:Linux服务器运维最佳实践》读书笔记

    首先,这本书是Linux.CN赠送的,多谢啦~ http://linux.cn/thread-12733-1-1.html http://linux.cn/thread-12754-1-1.html ...

  3. bzoj1251 序列终结者(splay)

    人生第一发splay,写得巨丑,最后忘记了push_down以后要将子节点maintain 9k代码不忍直视 #define NDEBUG #include<cstdio> #includ ...

  4. 【LeetCode】242 - Valid Anagram

    Given two strings s and t, write a function to determine if t is an anagram of s. For example,s = &q ...

  5. Python cookbook-读书笔记01

    1 数据结构和算法 1.1 Unpacking a sequence into separate variable(解包,赋值) >>> data = [ 'ACME', 50, 9 ...

  6. 基于Heritrix的特定主题的网络爬虫配置与实现

    建议在了解了一定网络爬虫的基本原理和Heritrix的架构知识后进行配置和扩展.相关博文:http://www.cnblogs.com/hustfly/p/3441747.html 摘要 随着网络时代 ...

  7. android系统的文件夹选择器

    aFileChooser: https://github.com/iPaulPro/aFileChooser/issues, 这个是最适合android的文件选择器,看看有无可能改成文件夹选择器. f ...

  8. 随手记录一个 firefox的backgroundPostion-x和-y的问题

    今天帮大师写了一天项目,后来在测试一个显示升序和降序的标签上面,我使用了一个backgroundPosition-y来判断当前icon的状态,却无法不管是使用闭包还是个钟手段,在 firefox下面总 ...

  9. Northwind数据库表字段介绍

    ① Categories:种类表 相应字段: CategoryID :类型ID: CategoryName:类型名; Description:类型说明; Picture:产品样本 ② Customer ...

  10. Apache Spark 架构

    1.Driver:运行 Application 的 main() 函数并且创建 SparkContext. 2.Client:用户提交作业的客户端. 3.Worker:集群中任何可以运行 Applic ...