C#泛型类的静态构造函数及静态成员[经典]

 C#泛型类的静态构造函数及静态成员[经典]

 

静态构造函数总是至多被调用一次吗?静态构造函数一定会被调用吗?看如下反例:

namespace ConsoleApplication1
{
    class Program:A<float>
    {
        static Program()
        {
            Console.WriteLine("Class Program static construct invoked.");
        }

        static void Main(string[] args)
        {
            Console.WriteLine(B.SomeValue++);
            Console.WriteLine(C.SomeValue++);
            Console.WriteLine(D.SomeValue++);
            Console.WriteLine(E.SomeValue++);
            Console.WriteLine(E.SomeValue2++);

            new F();
            new F();

            Console.ReadKey();

        }
    }

    class A<T>
    {
        public static int SomeValue=0;

        public A()
        {
            Console.WriteLine("Class A<{0}> dynamic construct invoked.", typeof(T).Name);
        }


        static A()
        {
            Console.WriteLine("Class A<{0}> static construct invoked.",typeof(T).Name);
        }
    }

    class B : A<string>
    {
        static B()
        {
            Console.WriteLine("Class B static construct invoked.");
        }
    }


    class C : A<int>
    {
        static C()
        {
            Console.WriteLine("Class C static construct invoked.");
        }
    }

    class D : A<int>
    {
        static D()
        {
            Console.WriteLine("Class D static construct invoked.");
        }
    }

    class E : A<float>
    {
        public static int SomeValue2 = 0;
        static E()
        {
            Console.WriteLine("Class E static construct invoked.");
        }
    }

    class F : A<bool>
    {
        public F()
        {
            Console.WriteLine("Class F dynamic construct invoked.");
        }

        static F()
        {
            Console.WriteLine("Class F static construct invoked.");
        }
    }

}


输出 如下:
Class Programe static construct invoked.
Class A<String> static construct invoked.
0
Class A<Int32> static construct invoked.
0
1
Class A<Single> static construct invoked.
0
Class E static construct invoked.
0
Class F static construct invoked.
Class A<Boolean> static construct invoked.
Class A<Boolean> dynamic construct invoked.
Class F dynamic construct invoked.
Class A<Boolean> dynamic construct invoked.
Class F dynamic construct invoked.

对输出结果分析如下:

//程序运行实际上是Framework调用Program 的Main静态方法,但不会实例化Program
Class Program static construct invoked.  
// 实际上静态成员并不支持继承,C#编译器会在底层将B.SomeValue翻译成A<string>.SomeValue
//所以被 加载的不是B,而是A<string>
Class A<String> static construct invoked. 
0
//同样此处C.SomeValue被翻译成A<int>.SomeValue
Class A<Int32> static construct invoked.
//诧异?被继承的SomeValue不是被“加加”了吗, 为何此处还是0
0
//看到了吧,SomeValue确实被“加加”了,不过A<string>与A<int>属 于不同的类型
//里面的SomeValue也是相互独立的
1
//E.SomeValue被翻译成 A<float>.SomeValue
Class A<Single> static construct invoked.
0
//此处的E.SomeValue2远远本本的就是E.SomeValue2当然E的静态构造函数会被执行。
// 现在我们才发觉B/C/D三者的静态构造函数都没被执行,原因呢,刚才也说了,实际上
//上面的B/C/D的引用在底层都被翻译成了A的封闭类, 所以加载的并不是B/C/D本身,而是
//相应的封闭类
Class E static construct invoked.
0
// 现在再来温习一下静态构造方法与构造方法的执行顺序
//因为new的是F,所以F首先被加载,进而执行F的静态构造
Class F static construct invoked.
//加载F后发现F是从A<bool>继承的,进而去加载 A<bool>,于是A<bool>的静态构造被执行
Class A<Boolean> static construct invoked.
//首先执行基类的构造方法
Class A<Boolean> dynamic construct invoked.
//而后是F自己的构造方法
Class F dynamic construct invoked.
//此两句因为A<bool>与F以被加载,静态构造已被执行,因而直接按顺序从低往高调用构造方法
Class A<Boolean> dynamic construct invoked.
Class F dynamic construct invoked.

QQ 1163551688
总结:
1.泛型类的各封闭类,属于不同的类,各自有自己独立的静态空间
2. 静态成员实际上不支持继承,C#编译器在底层将实际的引用确定成静态成员定义者
3.静态构造函数不一定会被执行,因为有的类,在执行过程中不会被 加载
4.静态构造函数确实是总是至多被调用一次,但是泛型类的静态构造要站在另一个角度考虑
5.类的构造函数执行顺序是自底而上
6. 类的静态构造函数执行顺序是不能确定的,因为编程过程中,类的使用顺序是不定的,静态构造函数总是在类第一次被用到的地方执行

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值