C# 的静态构造函数和BeforeFieldInit含义

发布于:2022-12-28 ⋅ 阅读:(640) ⋅ 点赞:(0)

1、静态初始化函数:

静态初始化函数,C#语法可以保证在一个程序中只调用一次,但是会去掉默认的beforefieldinit 标记
(C#默认会加),会导致加载时机的变化:

  • 首次访问该类型的任何静态或实例字段
  • 首次调用该类型的任何静态、实例或虚拟方法

2、BeforeFieldInit 的意义

C#在访问静态函数的时候,可能会初始化该类,具体的时机不确定,有可能是程序刚开始就初始化,也可能
最后访问具体属性的时候才初始化;具体加载时机由CLR决定。

这篇文章讲的非常不错,可以看看

3、实现更好的c#懒汉模式加载


内部类+静态构造函数,CLR保证静态构造函数只会加载一次,

C#调试代码如下所示,添加和不添加静态构造函数,类的实例化时间会不同


using System;

namespace ConsoleApp1
{

    class FirstType
    {
        public static string x = EchoAndReturn("In type initializer FirstType");
        public static void F() { Console.WriteLine("FirstType F"); }
        FirstType() { Console.WriteLine("FirstType is inited!!"); }

        static FirstType() { } // 加了这个函数之后,就会在编译的时候放弃默认的beforeFieldInit字段,当调用静态函数F时,就会初始化静态成员

        public static string EchoAndReturn(string s)
        {
            Console.WriteLine(s);
            return s;
        }
    }

    class SecondType
    {
        public static string x = EchoAndReturn("In type initializer SecondType");
        static SecondType() { }
        public static void F() { Console.WriteLine("SecondType F"); }
        SecondType() { Console.WriteLine("SecondType is inited!!"); }

        public static string EchoAndReturn(string s)
        {
            Console.WriteLine(s);
            return s;
        }
    }

    class Program
    {

        public static void DoSomething(bool which)
        {
            if (which)
            {
                FirstType.F();
            }
            else
            {
                SecondType.F();
            }
        }

        public static void Main()
        {
            DoSomething(true);
        }
    }
}


总结

  • 静态构造函数:静态构造函数的添加需要慎重 (能不加就不加,有BeforeFieldInit标记的,CLR会有优化),要知道添加的具体含义,因为添加了之后会去掉该类的BeforeFieldInit标志,这个标志是CLR优化效率用的,主要作用就是尽量延迟加载(lazy loading),也就是到真正使用的时候才加载。
  • BeforeFieldInit:C#会给类默认加的标志(除非类显示添加了静态构造函数),会进行相应的优化。
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到