在C#中,静态和非静态的特征对于咱们来讲是再熟悉不过了,可是不多看到有一篇文章去好好地总结静态和非静态它们之间的不一样,为了帮助你们更好地去理解静态和非静态特征, 因此将在这篇文章中帮你们全面总结下它们之间的不一样,包括静态类,静态成员和静态构造函数。但愿在你们巩固基础的时候能够拿出来好好复习下的。下面废话很少了,直接进入咱们今天的主题。程序员
在自定义类或看.NET Framework类库中均可以发现,类中大部分都是具体实例特征(也就是没有static标识的),同时咱们也能看到一些具备静态特征的类或成员,例如咱们常用的Console类以及WriteLine方法就是静态的。然而有些朋友会疑惑,为何还要有静态特征的呢?干脆都定义为实例的好了? 而后静态特征的存在确定有它存在的缘由的,并非咱们就是要这么定义的,其实我一直认为不论是什么都是源于生活的, 技术的实现也是同样,好比咱们开发程序,须要掌握技术外,其实更重要的是业务逻辑这块的,若是你都不知道你开发的东西是怎样的一个流程,即便你技术再牛作出来的东西都是反人类的东西(也就是指不符合用户的用户习惯和以前的一个业务需求),其实静态特征的存在也是源于生活的,对于类比如就是咱们现实生活中的人或事物,静态特征和非静态特征就比如生活中人或事物具备的特征, 咱们询问人的时候或者电视剧警察查案件的时候,都会听到这样一句话 "那我的有什么特征?"或 “嫌疑犯有什么特征?多高,年龄等” 其实高度、年龄、性别都是一我的的特征,因此这些在语言范畴就须要为其进行定义了,也就是咱们定义的实例成员了,然而有些特征须要被全部对象实例所共有的,这些特征在语言范畴就定义为静态特征,具体哪些特征能够定义为静态特征呢? 其实这点同样是源于生活的,因此咱们在开发软件的过程当中,必不可少的一个流程就是需求分析了,只有在了解客户需求的条件下才能进行以后的全部流程的, 例如一个班级有不少学生,每一个学生是一个实体,在语言范畴就能够定义一个类,当咱们须要一个学生的时候就能够经过new 关键字建立一个出来(说到这里又让我想到了恶搞泰囧的图片——你有对象吗?没对象,大家程序员能够本身new一个啊?),然而咱们建立出来的学生他们都有一些共有的特征,如同一个班级,学校等, 若是咱们把班级、学校这样的特征也定义为实例的话,那么咱们不是每次建立对象实例的时候都为这些共有的特征分配一次内存的,这样不只对内存空间的浪费也是不知足生活常识的,此时咱们就能够把班级、学校这样的特征定义为静态特征,这样全部实例均可以共享这两个特征,而且不须要为每一个对象实例分配内存。编程
静态类和非静态类在C#中定义基本是同样的,只是静态类定义须要加上static修饰符而已。下面就直接总结下它们之间的区别:ide
静态类只能包含静态成员,不然会抛出编译错误;然而非静态类既能够包含非静态成员也能够包含静态成员函数
静态类是不能实例化,之因此不能实例化,是由于静态类会致使C#编译器将该类同时标记为abstract和sealed,而且编译器不会在类型中生成一个实例的构造函数,从而致使静态类不能实例化,具体缘由能够见下图;非静态类能够,而且静态成员的访问只能经过类来进行访问,由于静态成员是属于类的。工具
publicstaticclass StaticClass { privatestaticstring name; }
上面代码用IL反汇编程序获得的IL代码结构为:性能
静态构造函数用来初始化类中的静态成员的,包括静态字段和静态属性,而且静态构造函数是不能带有参数、不能有访问修饰符,静态构造函数的调用是由CLR第一次调用类成员以前执行的。this
下面仍是直接总结下静态构造函数与实例构造函数之间的区别:spa
静态构造函数能够与无参的实例构造函数同时存在指针
静态构造函数在CLR加载类时执行,然而实例构造函数在每次实例建立时都会执行code
静态构造函数只能对静态成员初始化,不能对非静态成员进行初始化操做,然而实例构造函数,既能够初始化实例成员也能够初始化静态成员,但静态只读字段除外
静态构造函数只被执行一次,可是CLR也不能肯定它何时被执行,它的执行方式有两种,precise和before-field-init,这个会在下一篇文章中详细给你们介绍,这里先提出给你们一个思考的空间。而实例构造函数在每次建立对象实例时都会被执行,建立几个就会执行几回
一个类只能有一个静态构造函数,却能够有多个实例构造函数
静态字段的初始值在静态构造函数调用以前被指定,构造函数的执行顺序大体以下图所示:
下面就直接总结下它们之间的区别:
静态成员包括静态字段和静态字段,静态字段通常实现为private,静态属性通常实现为public,从而来体现类的封装性
静态成员和类相关联,不依赖于对象而存在,只能由类来访问;实例成员与具体类相关联,只能由对象实例访问
静态成员无论建立多少实例对象,都在内存中只有一份,实例成员每建立一个实例对象,都会在内存中分配一块内存区域。
相似于静态字段和属性,静态方法共享代码段,一样以static关键字来标识静态方法,对于他们之间的区别总结为:
静态方法只能访问静态成员和方法,可是能够间接经过建立实例对象来访问实例字段、属性和方法;实例方法既能够访问实例成员也能够访问静态成员
静态方法由类方法‘实例方法由对象访问
静态方法不能引用this关键字,而实例方法能够
静态方法不能被标识为virtual、abstract或override,静态方法能够被派生访问,可是不能被派生类重写
Main方法为静态的,因此Main方法不能直接访问类中的实例字段、属性和方法,不然编译器会报错
静态方法通常用于做为通用的工具类来实现
在性能上,静态方法和实例方法的差异不大。由于,它们都是在JIT加载类的时候分配内存的,不一样的是静态方法是以类为引用,而实例方法是以对象为引用,建立实例时,不会再为静态方法分配内存,全部实例对象共用一个类的方法代码,因此,静态方法和实例方法的调用,区别仅在于静态方法能够直接调用,而实例方法须要当前对象指针指向该方法,在性能上差不并不大。
到这里,本文章的内容就介绍完了,经过对静态特征和非静态特征的由来来揭开一些都是源于生活的观点,而后再详细分析了静态特征与非静态特征在C#语言中的区别,但愿这些总结能够帮助你们在复习基础知识的时候能够有用。同时也是本身的一个复习笔记的。