构造函数这个概念,在我们刚开始学习编程语言的时候,就被老师一遍一遍的教着。亲,现在你还记得静态构造函数的适用场景吗?如果没有,那么我们一起来复习一下吧。

静态构造函数是在构造函数方法前面添加了static关键字之后形成的,并且没有修饰符(public,private),没有参数。

静态构造函数有哪些特点呢:

  1. 静态构造函数没有修饰符修饰(public,private),因为静态构造函数不是我们程序员调用的,是由.net 框架在合适的时机调用的。
  2. 静态构造函数没有参数,因为框架不可能知道我们需要在函数中添加什么参数,所以规定不能使用参数。
  3. 静态构造函数前面必须是static 关键字。如果不加这个关键字,那就是普通的构造函数了。
  4. 静态构造函数中不能实例化实例变量。(变量可以分为类级别和实例级别的变量,其中类级别的有static关键字修饰)。
  5. 静态函数的调用时机,是在类被实例化或者静态成员被调用的时候进行调用,并且是由.net框架来调用静态构造函数来初始化静态成员变量。
  6. 一个类中只能有一个静态构造函数。
  7. 无参数的静态构造函数和无参数的构造函数是可以并存的。因为他们一个属于类级别,一个属于实例级别,并不冲突。
  8. 静态构造函数只会被执行一次。并且是在特点5中的调用时机中进行调用。
  9. 就像如果没有在类中写构造函数,那么框架会为我们生成一个构造函数,那么如果我们在类中定义了静态变量,但是又没有定义静态构造函数,那么框架也会帮助我们来生成一个静态构造函数来让框架自身来调用。

上面几个特点都是理论性的,我们来做一个找错题,帮助我们一起来学习静态构造函数。

 1     public class C
2 {
3 public static string BB;
4 public static C()
5 {
6 BB = "CC";
7 }
8 public static C(string mm)
9 {
10 BB = mm;
11 }
12 static C()
13 {
14 BB = "Right";
15 }
16 public C()
17 {
18 BB = "Wrong";
19 }
20 public C(string mm)
21 {
22 BB = mm;
23 }
24 }

VS编译提示的错误信息:

现在我们来做一个有意思的事情,验证静态构造函数的调用时机:

 1  class Program
2 {
3 static void Main(string[] args)
4 {
5
6 Console.WriteLine(A.strText);
7 Console.WriteLine(B.strText);
8 Console.Read();
9 }
10 }
11 public class A
12 {
13 public static string strText;
14 public string Text;
15 static A()
16 {
17 strText = "AAA";
18 }
19 public A()
20 {
21 Text = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
22 }
23 }
24 public class B:A
25 {
26 static B()
27 {
28 strText = "BBB";
29 }
30 public B()
31 {
32 Text = "BBBBBBBBBBBBBBBBB";
33 }
34 }

输出结果均为:AAA

我们来分析一下出现这个情况的原因所在,当显示A.strText的时候,因为strText是静态变量,所以框架会调用A的静态构造函数,此时strText的值为AAA.正确

当显示B.strText的时候,因为B继承自A,所以会首先调用A的静态构造函数,但是因为静态构造函数只会调用一次,所以不会调用A的静态构造函数,但是又因为strText属于类A,而不是B,所以B得静态构造函数不会执行,故输出的均为AAA。

但是如果我们把输出更改一下,输出结果就大不一样了。

 1     class Program
2 {
3 static void Main(string[] args)
4 {
5 B b = new B();
6 A a = new A();
7
8 Console.WriteLine(A.strText);
9 Console.WriteLine(B.strText);
10
11 Console.Read();
12 }
13 }
14 public class A
15 {
16 public static string strText;
17 public string Text;
18 static A()
19 {
20 strText = "AAA";
21 }
22 public A()
23 {
24 Text = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
25 }
26 }
27 public class B:A
28 {
29 static B()
30 {
31 strText = "BBB";
32 }
33 public B()
34 {
35 Text = "BBBBBBBBBBBBBBBBB";
36 }
37 }

请注意我在开始部分对类进行了实例化,那么此时的输出结果就是均为BBB。

为什么会有这样的情况出现呢,其实还是要从静态构造函数的调用时机入手。

首先我们实例化了B,此时会调用B的静态构造函数,但是因为strText是A的静态变量,所以首先会先调用A的静态构造函数将strText赋值为AAA,此时又会调用B的静态构造函数将strText赋值为BBB,所以此时strText的值应该为BBB,所以输出均为BBB。

c#静态构造函数与构造函数的更多相关文章

  1. java:利用静态字段和构造函数实现已建对象数查询

    问题:使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数. 请写一个类,在任何时候都可以向它查询"你已经创建了多少个对象?". 程序设计思想: 利用静态变量指定一个计数 ...

  2. c# 静态构造函数与构造函数的调用先后

    先上代码: 测试类: /// <summary> /// 构造函数 /// </summary> public RedisHelper() { Console.WriteLin ...

  3. C++的默认构造函数与构造函数

    今天看书,忽然发现自己对默认构造函数/构造函数的理解很模糊,在实际项目中写类时,这些细节问题并没有涉及到.因此,就专门对着<C++ Primer Plus>将默认构造函数/构造函数这一块简 ...

  4. python中的构造函数和构造函数和析构函数的作用

    构造函数和构造函数和析构函数都属于python中的特殊方法 其中的“__del__”就是一个析构函数了,当使用del 删除对象时,会调用他本身的析构函数,另外当对象在某个作用域中调用完毕,在跳出其作用 ...

  5. C++类构造函数、拷贝构造函数、复制构造函数、复制构造函数、构造函数显示调用和隐式调用

    一. 构造函数是干什么的   class Counter   {   public:            // 类Counter的构造函数            // 特点:以类名作为函数名,无返回 ...

  6. c#静态构造函数 与 构造函数 你是否还记得?

    构造函数这个概念,在我们刚开始学习编程语言的时候,就被老师一遍一遍的教着.亲,现在你还记得静态构造函数的适用场景吗?如果没有,那么我们一起来复习一下吧. 静态构造函数是在构造函数方法前面添加了stat ...

  7. C#构造函数、私有构造函数、静态构造函数与构造函数执行顺序

    默认构造函数,如果没有为类指定任何构造函数,编译器会自动为类创建一个无参构造函数,用以初始化类的字段:如果为类编写了构造函数,那么编译器就不会再自动生成无参构造函数了.ps.C#不允许用户为结构定义无 ...

  8. c#静态构造函数 与 构造函数 你是否还记得?(转载)

    构造函数这个概念,在我们刚开始学习编程语言的时候,就被老师一遍一遍的教着.亲,现在你还记得静态构造函数的适用场景吗?如果没有,那么我们一起来复习一下吧.静态构造函数是在构造函数方法前面添加了stati ...

  9. 静态代码块&非静态代码块&构造函数

    总结:静态代码块总是最先执行.非静态代码块跟非静态方法一样,跟对象有关.只不过非静态代码块在构造函数之前执行.父类非静态代码块.构造函数执行完毕后(相当于父类对象初始化完成), 才开始执行子类的非静态 ...

随机推荐

  1. redis的使用及方法

    一.redis (1).redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset ...

  2. mysql导入source数据库

    首先要确保数据库存在,如果不存在则创建 方法1 source 很智能,很方便,很快捷. # mysql -uroot -p Enter password: Welcome to the MySQL m ...

  3. 智课雅思词汇---二十七、形容词后缀-ant/-ent

    智课雅思词汇---二十七.形容词后缀-ant/-ent 一.总结 一句话总结: ...的 后缀:-ant ①[形容词后缀] 大部分与-ance或-ancy,相对应,表示属于...的.具有...性质的 ...

  4. RJ45接口

    什么是rj45接口? rj45是各种不同接头的一种类型,通常用于数据传输,最常见的应用为网卡接口. 常见的RJ45接口有两类:用于以太网网卡.路由器以太网接口等的DTE类型,还有用于交换机等的DCE类 ...

  5. Rails 5 Test Prescriptions 第6章Adding Data to Tests

    bcreate the data quickly and easily.考虑测试运行的速度. fixtures and factories.以及下章讨论的test doubles,还有原生的creat ...

  6. Eclips安装SVN插件

    1.eclipse -> Help ->Install New Software->add 2.弹出窗的"Name"和"URL"中输入如下内容 ...

  7. tflearn tensorflow LSTM predict sin function

    from __future__ import division, print_function, absolute_import import tflearn import numpy as np i ...

  8. qt Cannot connect creator comm socket /tmp/qt_temp.S26613/stub-socket: No such

    Tool->Options->Environment->General 将terminal改为 xterm -e

  9. asp.net(c#)开发中的文件上传组件uploadify的使用方法(带进度条)

    上文件传很常见,现在就文件上传利用HTML的File控件(uploadify)的,这里为大家介绍一下(uploadify)的一些使用方法.在目前Web开发中用的比较多的,可能uploadify(参考h ...

  10. [批处理]Oracle启动助手

    前段日子开始学Oracle数据库,但是由于Oracle数据库的服务启动时间很长 所以机房的里面所有电脑的Oracle服务全部是被禁用的 所以每次上机使用的时候都要先进服务管理,然后把禁用更改为手动模式 ...