开始复习起来C#基础知识了!
静态构造函数
C#普通的构造函数大家应该都是相当了解的了,那么在静态构造函数中只需将函数声明关键字使用static即可,通常静态构造函数初始化类的静态字段。
来看看常见的问题
Q:静态构造函数与实例构造函数相同点?
A:1.静态构造函数的名称必须与类名相同。
2.构造函数不能返回值
Q:静态构造函数与实例构造函数不同点?
A:1.静态构造函数声明中使用static关键字
2.类只能有一个静态构造函数,并且不能带参数
3.静态构造函数不能有访问修饰符
Q:类中可以既有静态构造函数和实例构造函数么?
A:当然!
Q:静态构造函数可以访问所在类的实例成员么?
A:只能访问静态成员,因此也不能使用this访问器
Q:静态构造函数可以多次调用么?
A:最多调用一次!
Q:静态构造函数可以被继承么?
A:当然…不可以!
Q:静态构造函数是如何调用的呢?
A:我们在程序中不能显式调用静态构造函数,系统会自动调用它们。
Q:那系统会在什么时候调用呢?
A:1.类的任何实例被创建之前
2.类的任何静态成员被引用之前
接下来直接看两段代码了解一下具体
class Program
{
static void Main(string[] args)
{
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";
}
}
根据上面的常见问题解答 对于理解静态构造函数就方便多了。
我们首先要访问类A的静态成员strText,所以调用了类A的静态构造函数,给strText赋值为AAA,所以第一行就是AAA。接着看类B,由于B继承了A,所以调用A的静态构造函数,但是之前A已经调用过了,所以不再使用,而strText是A类的静态成员,所以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";
}
}
这次我们是将A B两个类实例化了对象,依次来分析一下
首先实例化了B的对象,所以我们要从B中调用静态构造函数,但是由于B继承自A类,所以先调用A类的静态构造函数,strText为AAA,调用完A类后再调用B类自身的静态构造函数,所以strText修改为BBB。接着我们再看A实例化了对象,要调用自身的静态构造函数,但是之前被B调用掉了(只能被调用一次)所以无法调用自身的静态构造函数了。所以很明显最后输出的是两行BBB
那肯定有人要问了,是不是因为你在代码里先实例化了B再实例化了A才这样的,当然可以做个尝试,改变一下顺序,先实例化A再实例化B也是同样的结果啦。分析一下:如果先实例化A,调用自身A的静态构造函数,将strText=AAA,然后实例化B,B继承自A,所以先调用A的静态构造函数,但是已经被A之前调用过了所以无法调用,接着再调用自身B的静态构造函数将strText==BBB。所以结果显而易见还是两行BBB
静态构造函数就复习到这了,如果有遗漏的或者有出错的麻烦指出,谢谢!