静态构造函数, 静态成员初始化/调用顺序

1)第一次调用类的任何成员之前,执行静态成员的初始化动作,执行顺序是:静态成员初始化--->静态构造函数--->调用类的某成员(构造器,静态字段/属性/函数,)

2)静态成员在第一次被访问之前并且在调用静态构造函数(如有存在)之前进行初始化。同1).

3)在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数。调用静态构造函数之前会先做静态成员的初始化。同1),2)。

4)如果类包含静态字段,请提供在加载类时初始化这些字段的静态构造函数。

5)在应用程序域的生存期内,静态类一直保留在内存中。

示例程序,main函数中分别打开TestCast1,2,3,4. 观察运行结果:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace static_const_readonly
{
    class MyClass
    {
        public static readonly int Count = 0;
        public static MyTest TEST = new MyTest();

        static MyClass()
        {
            Console.WriteLine("static MyClass() ctor.");
            TEST = new MyTest();
        }

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

        public MyClass()
        {
            Console.WriteLine("MyClass() ctor");
        }
    }

    class MyTest
    {
        public MyTest()
        {
            Console.WriteLine("My Test ctor.");
        }
    }

    class Program
    {
         static void TestCast1()
        {
            Console.WriteLine("test starts.");
            MyClass myobject = new MyClass(); // call ctor
        }

         static void TestCast2()
         {
             Console.WriteLine("test starts.");
             Console.WriteLine("static MyClass.Count = {0}.", MyClass.Count); // get MyClass.Count
         }

        static void TestCast3()
        {
            Console.WriteLine("test starts."); // not refer to MyClass
            Console.WriteLine(typeof(MyClass));
        }

        static void TestCast4()
        {
            Console.WriteLine("test starts."); // not refer to MyClass
            MyClass.FuncStatic();
        }

        static void TestCast5()
        {
            Console.WriteLine("test starts."); // not refer to MyClass
        }

        static void Main(string[] args)
        {
            //TestCast1();
            //TestCast2();
            //TestCast3();
            TestCast4();
            // TestCast5();
        }
    }
}

TestCase1结果:

test starts.
My Test ctor.
static MyClass() ctor.
My Test ctor.
MyClass() ctor

TestCase2结果:

test starts.
My Test ctor.
static MyClass() ctor.
My Test ctor.
static MyClass.Count = 0.

TestCase3结果:

test starts.
static_const_readonly.MyClass

TestCase4结果:

test starts.
My Test ctor.
static MyClass() ctor.
My Test ctor.
static void FuncStatic().

TestCase5结果:

test starts.

总结:创建实例,引用/调用静态字段/函数会导致CLR 初始化静态成员和调用静态构造函数。只是获取type类型或者没有关于类的任何引用代码,静态成员的初始化和静态构造函数不会执行。

时间: 2024-10-07 15:16:07

静态构造函数, 静态成员初始化/调用顺序的相关文章

子类继承父类的时候构造器和非静态自由块的调用顺序

body { font-family: 微软雅黑,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5; } html, body { } h1 { font-size:1.5em; font-weight:bold; } h2 { font-size:1.4em; font-weight:bold; } h3 { fon

派生类的构造函数学习之调用顺序

派生类构造函数的一般格式为: 记:B为派生类 ,A为基类 B::B(<构造函数总参数表>):A(<参数表1>),<子对象名>(<参数表2>),...... 派生类构造函数调用顺序为:基类构造函数.子对象构造函数(如果有).派生类构造函数. 对象生命周期结束后,会执行析构函数,析构函数调用顺序和构造函数调用顺序相反. 原文地址:https://www.cnblogs.com/strivingforever/p/8267309.html

静态成员初始化与构造函数的先后顺序

最近公司有个项目的数据库需要从Oracle迁移到SQLServer中,为了方便我引入一个轻量级的ORM框架PetaPoco,并且根据相关业务进行了简单封装.之前公司的项目架构极其简陋,功能很难扩展,很少用什么框架,代码中用了很多静态方法,可能觉得直接用类名点出方法很方便的缘故,而不去考虑服务器的负担,代码分层混乱,让我不敢相信这是一家上市公司的实力.也有可能只是.NET这块比较薄弱吧.作为应届毕业生,毕竟来这里还不到一个月. 言归正传,因为项目中都是静态方法,而我加入封装好的代码时,产生了一个疑

静态构造函数

先看一道常见题目,以下代码的执行结果是什么? class A { public static int X = B.Y + 1; static void Main(string[] args) { Console.WriteLine(X); } } class B { public static int Z = 10; public static int Y; static B() { Console.WriteLine(Z); Y = A.X + 1; } } 一.定义 由名称可知,静态构造函数

由单例模式学到:静态构造函数和静态字段

编译器在编译的时候,会事先分析所需要的静态字段,如果这些静态字段所在的类有静态的构造函数,则忽略静态字段的初始化,否则先进行静态字段的初始化.对类的静态成员初始化的顺序取决于在Main函数中的引用顺序,先引用到的先进行初始化,但如果类的静态成员的初始化依赖于其它类的静态成员,则会先初始化被依赖类的静态成员.而带有静态构造函数的类的静态字段,只有在引用到的时候才进行初始化. 接下来,用实例来对以上的一段总结性的描述逐句分析: 1.编译器在编译的时候,会事先分析所需要的静态字段,如果这些静态字段所在

【转载】关于C#静态构造函数的几点说明

一.定义 静态构造函数是C#的一个新特性,其实好像很少用到.不过当我们想初始化一些静态变量的时候就需要用到它了.这个构造函数是属于类的,而不是属于哪里实例的,就是说这个构造函数只会被执行一次.也就是在创建第一个实例或引用任何静态成员之前,由.NET自动调用. class SimpleClass { // Static constructor static SimpleClass() { // } } 在使用静态构造函数的时候应该注意几点: 1.静态构造函数既没有访问修饰符,也没有参数.因为是.N

关于C#的静态类和静态构造函数

静态构造函数是C#的一个新特性,其实好像很少用到.不过当我们想初始化一些静态变量的时候就需要用到它了.这个构造函数是属于类的,而不是属于哪里实例的,就是说这个构造函数只会被执行一次.也就是在创建第一个实例或引用任何静态成员之前,由.NET自动调用. class SimpleClass { // Static constructor static SimpleClass() { // } } 在使用静态构造函数的时候应该注意几点: 1.静态构造函数既没有访问修饰符,也没有参数.因为是.NET调用的

C#静态构造函数

静态构造函数用于初始化任何静态数据,或用于执行仅需执行一次的特定操作.在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数. 静态构造函数具有以下特点: 静态构造函数既没有访问修饰符,也没有参数. 在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类. 无法直接调用静态构造函数. 在程序中,用户无法控制何时执行静态构造函数. 静态构造函数的典型用途是:当类使用日志文件时,将使用这种构造函数向日志文件中写入项. 静态构造函数在为非托管代码创建包装类时也很有用,此时该构

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

构造函数这个概念,在我们刚开始学习编程语言的时候,就被老师一遍一遍的教着.亲,现在你还记得静态构造函数的适用场景吗?如果没有,那么我们一起来复习一下吧. 静态构造函数是在构造函数方法前面添加了static关键字之后形成的,并且没有修饰符(public,private),没有参数. 静态构造函数有哪些特点呢: 静态构造函数没有修饰符修饰(public,private),因为静态构造函数不是我们程序员调用的,是由.net 框架在合适的时机调用的. 静态构造函数没有参数,因为框架不可能知道我们需要在函