2.静态类成员、静态构造函数、静态类

2.1 静态类成员和实例类成员

类成员分为成员变量和成员函数两种,有static修饰的类成员称为静态类成员,分为静态成员变量(类变量或类成员变量)和静态成员函数(类方法),没有static修饰的分别称为实例变量和实例方法。

类变量是被所有对象共享的,即所有对象的这个类变量是分配到同一个内存空间的,一个对象修改了这个类变量,那么其他对象的这个类变量的值也随之改变。

同样,类方法也是被所有对象共享的,所有对象的这个类方法被分配到的是同一个内存空间。

实例成员是对象所独有的,每个对象的实例成员分配到的内存空间不同。

类方法只能操作类变量,不能操作实例变量,实例方法可以操作任何类型的变量;类方法只能调用类中的其他类方法,实例方法可以调用类的任何方法。

2.2静态构造函数

使用静态成员变量时需要预先初始化,可以在定义时就提供一个初始值,但是若是要进行更复杂的初始化,或者在访问静态成员之前进行其他操作就要用到静态构造函数。

静态构造函数用于对静态成员进行初始化,静态构造函数用static修饰,不能有访问修饰符,也不能有任何参数,没有返回值且不能用void修饰。

静态构造函数不能手动调用,在如下情况系统会自动调用,且每个类只会调用一次

1)创建包含静态构造函数的类实例时;

2)第一次访问包含静态构造函数的静态成员时。

静态构造函数只能初始化静态成员变量,不能初始化实例变量,且每个类只有一个静态构造函数

我们来做一个找错题,帮助我们一起来学习静态构造函数。

public class C
    {
        public static string BB;
        public static C()
        {
            BB = "CC";
        }
        public static C(string mm)
        {
            BB = mm;
        }
        static C()
        {
            BB = "Right";
        }
        public C()
        {
            BB = "Wrong";
        }
        public C(string mm)
        {
            BB = mm;
        }
    }

VS编译提示的错误信息:

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

 class Program
    {
        private static object lokk = new object();

        static void Main(string[] args)
        {
            Console.WriteLine(B.strText);
            Console.WriteLine(A.strText);

            Console.ReadLine();
        }
       
    }

 class A
    {
        public static  string strText;
        public string Text;

        static A()
        {
            strText = "AAA";
        }

        public A()
        {
            Text = "AAAAAAAAAA";
        }
    }


    class B:A
    {
        static B()
        {
            strText = "BBB";
        }

        public B()
        {
            Text = "BBBBBBBBBBBBBBB";
        }
    }

输出结果均为:AAA

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

当显示B.strText的时候,虽然B继承自A,但是strText是属于A的,所以会调用A的静态构造函数初始化strText,而B的静态构造函数得不到调用,故输出的均为AAA。

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

class Program
    {
        static void Main(string[] args)
        {
            B b = new B();
            A a = new A();

            Console.WriteLine(A.strText);
            Console.WriteLine(B.strText);
          
            Console.Read();
        }
    }
    public class A
    {
        public static string strText;
        public string Text;
        static A()
        {
            strText = "AAA";
        }
        public A()
        {
            Text = "AAAAAAAAAAAAAAAAAAAAAAAAAA";
        }
    }
    public class B:A
    {
        static B()
        {
            strText = "BBB";
        }
        public B()
        {
            Text = "BBBBBBBBBBBBBBBBB";
        }
    }

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

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

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

参考https://www.cnblogs.com/jiagoushi/p/3775046.html

 C#对象成员的初始化顺序参考https://www.cnblogs.com/lidaying5/p/10511205.html

2.3静态类

只包含静态成员的类叫做静态类,静态类不包含实例构造函数,不能实例化,也不能继承,如Console类

    static  class A
    {
        public static  string strText;
        static A()
        {
            strText = "AAA";
        }
       
    }
原文地址:https://www.cnblogs.com/lidaying5/p/10473708.html