首页 > 编程知识 正文

C# 之 静态方法和非静态方法对比

时间:2023-05-04 15:03:42 阅读:201892 作者:4989

C#静态成员

静态成员属于类所有,为各个类的实例所公用,无论类创建了几多实例,类的静态成员在内存中只占同一块区域。

、静态成员属于类所有,非静态成员属于类的实例所有。、每创建一个类的实例,都市在内存中为非静(动)态成员新分派一块存储;

静态数据成员区别于动态数据成员,静态变量并不是稳定的,只是静态变量在声明的时候不管有没有赋值,都会凭据它的类型分派对应的内存空间,他的可访问性和作用区间与动态变量是一样的

非静态类可以包含静态方法、字段、属性或事件。 即使未创建类的任何实例,也可对类调用静态成员。 静态成员始终按类名(而不是实例名称)进行访问。 静态成员只有一个副本存在(与创建的类的实例数有关)。 静态方法和属性无法在其包含类型中访问非静态字段和事件,它们无法访问任何对象的实例变量,除非在方法参数中显式传递它。
更典型的做法是声明具有一些静态成员的非静态类(而不是将整个类都声明为静态)。 静态字段的两个常见用途是保留已实例化的对象数的计数,或是存储必须在所有实例间共享的值。
静态方法可以进行重载,但不能进行替代,因为它们属于类,而不属于类的任何实例。
虽然字段不能声明为 static const,不过 const 字段在其行为方面本质上是静态的。 它属于类型,而不属于类型的实例。 因此,可以使用用于静态字段的相同 ClassName.MemberName 表示法来访问常量字段。 无需进行对象实例化。

通常我们调用方法的三种形式: class Program { static void Main(string[] args) { //第一种方式, 声明实例,调用实例方法 ClassName someClass = new ClassName(); ClassName.Method(); //第二种方式,通过一个静态的实例,去调用实例方法 ClassName.instance.Method(); //第三种方式,直接调用静态方法 ClassName.Method();}} 有时候我们对静态方法和实例化方法会有一些误解。

下文参考链接:https://blog.csdn.net/BIAOBIAOqi/article/details/6732117

1、大家都以为 “ 静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存。”

要知道一个.NET类型的静态方法是属于这个.NET类型的。而这个.NET类型是一个.NET 程序集的一部分。这个.NET程序集是被一个AppDomain装入到内存里面来的。这个AppDomain是可以从内存卸载的。一个有.NET CLR的进程里面可以有多于一个的AppDomain,第一个AppDomain之后的AppDomain都可以动态创建和卸载。这些AppDomain中的.NET程序集,既可以有静态方法,也可以有实例方法。不管是静态方法还是实例方法,都是随其程序集所在的AppDomain一起创建和卸载。第一个AppDomain在整个程序运行结束时也会最后被卸载。其中所含的.NET程序集自然也卸载

静态方法不存在常驻内存一说,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。

2、大家都以为 “ 静态方法在堆上分配内存,实例方法在堆栈上”

事实上所有的方法都不可能在堆或者堆栈上分配内存,方法作为代码是被加载到特殊的代码内存区域,这个内存区域是不可写的。

方法占不占用更多内存,和它是不是static没什么关系。
因为字段是用来存储每个实例对象的信息的,所以字段会占有内存,并且因为每个实例对象的状态都不一致(至少不能认为它们是一致的),所以每个实例对象的所有字段都会在内存中有一分拷贝,也因为这样你才能用它们来区分你现在操作的是哪个对象。
但方法不一样,不论有多少个实例对象,它的方法的代码都是一样的,所以只要有一份代码就够了。因此无论是static还是non-static的方法,都只存在一份代码,也就是只占用一份内存空间。
同样的代码,为什么运行起来表现却不一样?这就依赖于方法所用的数据了。主要有两种数据来源,一种就是通过方法的参数传进来,另一种就是使用class的成员变量的值……

3、大家都以为 “实例方法需要先创建实例才可以调用,比较麻烦,静态方法不用,比较简单”

事实上如果一个方法与他所在类的实例对象无关,那么它就应该是静态的,而不应该把它写成实例方法。所以所有的实例方法都与实例有关,既然与实例有关,那么创建实例就是必然的步骤,没有麻烦简单一说。

当然你完全可以把所有的实例方法都写成静态的,将实例作为参数传入即可,一般情况下可能不会出什么问题。

从面向对象的角度上来说,在抉择使用实例化方法或静态方法时,应该根据是否该方法和实例化对象具有逻辑上的相关性,如果是就应该使用实例化对象 反之使用静态方法。这只是从面向对象角度上来说的。

如果从线程安全、性能、兼容性上来看 也是选用实例化方法为宜。

我们为什么要把方法区分为:静态方法和实例化方法 ?

如果我们继续深入研究的话,就要脱离技术谈理论了。早期的结构化编程,几乎所有的方法都是“静态方法”,引入实例化方法概念是面向对象概念出现以后的事情了,区分静态方法和实例化方法不能单单从性能上去理解,创建c++,java,c#这样面向对象语言的大师引入实例化方法一定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。这样说的话,静态方法和实例化方式的区分是为了解决模式的问题。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。