一、引言

  在C#中,静态和非静态的特征对于我们来说是再熟悉不过了,但是很少看到有一篇文章去好好地总结静态和非静态它们之间的不同,为了帮助大家更好地去理解静态和非静态特征, 所以将在这篇文章中帮大家全面总结下它们之间的不同,包括静态类,静态成员和静态构造函数。希望在大家巩固基础的时候可以拿出来好好复习下的。下面废话不多了,直接进入我们的主题。

  二、为什么需要静态特征

  在自定义类或看.NET Framework类库中都可以发现,类中大部分都是具体实例特征(也是没有static标识的),同时我们也能看到一些具有静态特征的类或成员,例如我们经常使用的Console类以及WriteLine方法是静态的。然而有些朋友会疑惑,为什么还要有静态特征的呢?干脆都定义为实例的好了? 然后静态特征的存在肯定有它存在的原因的,并不是我们是要这么定义的,其实我一直认为不管是什么都是源于生活的, 技术的实现也是一样,比如我们开发程序,需要掌握技术外,其实更重要的是业务逻辑这块的,如果你都不知道你开发的东西是怎样的一个流程,即使你技术再牛做出来的东西都是反人类的东西(也是指不符合用户的用户习惯和之前的一个业务需求),其实静态特征的存在也是源于生活的,对于类好比是我们现实生活中的人或事物,静态特征和非静态特征好比生活中人或事物具有的特征, 我们询问人的时候或者电视剧警察查案件的时候,都会听到这样一句话 “那个人有什么特征?”或 “嫌疑犯有什么特征?多高,年龄等” 其实高度、年龄、性别都是一个人的特征,所以这些在语言范畴需要为其进行定义了,也是我们定义的实例成员了,然而有些特征需要被所有对象实例所共有的,这些特征在语言范畴定义为静态特征,具体哪些特征可以定义为静态特征呢? 其实这点一样是源于生活的,所以我们在开发软件的过程中,必不可少的一个流程是需求分析了,只有在了解客户需求的条件下才能进行之后的所有流程的, 例如一个班级有很多学生,每个学生是一个实体,在语言范畴可以定义一个类,当我们需要一个学生的时候可以通过new 关键字创建一个出来(说到这里又让我想到了恶搞泰?的图片——你有对象吗?没对象,你们程序员可以自己new一个啊?),然而我们创建出来的学生他们都有一些共有的特征,如同一个班级,学校等, 如果我们把班级、学校这样的特征也定义为实例的话,那么我们不是每次创建对象实例的时候都为这些共有的特征分配一次内存的,这样不仅对内存空间的浪费也是不满足生活常识的,此时我们可以把班级、学校这样的特征定义为静态特征,这样所有实例都可以共享这两个特征,并且不需要为每个对象实例分配内存。

  三、比较静态特征和非静态特征

  3.1 静态类与非静态类

  ● 静态类和非静态类在C#中定义基本是一样的,只是静态类定义需要加上static修饰符而已。下面直接总结下它们之间的区别:

  ● 静态类只能包含静态成员,否则会抛出编译错误;然而非静态类既可以包含非静态成员也可以包含静态成员

  ● 静态类是不能实例化,之所以不能实例化,是因为静态类会导致C#编译器将该类同时标记为abstract和sealed,并且编译器不会在类型中生成一个实例的构造函数,从而导致静态类不能实例化,具体原因可以见下图;非静态类可以,并且静态成员的访问只能通过类来进行访问,因为静态成员是属于类的。

publicstaticclass StaticClass    {        privatestaticstring name;    }

  上面代码用IL反汇编程序得到的IL代码结构为:

  3.2 静态构造函数与实例构造函数

  ● 静态构造函数用来初始化类中的静态成员的,包括静态字段和静态属性,并且静态构造函数是不能带有参数、不能有访问修饰符,静态构造函数的调用是由CLR第一次调用类成员之前执行的。

  ● 下面还是直接总结下静态构造函数与实例构造函数之间的区别:

  ● 静态构造函数可以与无参的实例构造函数同时存在

  ● 静态构造函数在CLR加载类时执行,然而实例构造函数在每次实例创建时都会执行