彩票走势图

C#静态方法和实例方法辨析和实例

转帖|其它|编辑:郝浩|2010-08-27 15:40:21.000|阅读 664 次

概述:本文将围绕c#静态方法和实例方法讨论一下。针对一些观点,如:"静态方法是常驻内存", 还有"静态方法比实例方法先装载",做一个辨析。同时讨论下何时用静态方法,何时用实例方法。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

  本文将围绕c#静态方法和实例方法讨论一下。针对一些观点,如:"静态方法是常驻内存";, 还有"静态方法比实例方法先装载",做一个辨析。同时讨论下何时用静态方法,何时用实例方法。

  前几日,在微软的好友发给我一个链接:《静态方法和实例化方法之间的区别你知道了嘛? 欢迎讨论!! - 问题最终 ...》,然后说这里某些观点需要澄清一下,希望我写一篇blog。我当时读了这篇blog. 文比较短,列举了静态方法和实例方法的几种案例,也没有论点,然后就请大家讨论。后面评论就比blog热闹多了。言辞也激烈,后来该blog作者干脆把这篇blog删了。现在已经看不到这篇blog了。现在我写这篇blog,一是针对一些观点做个辨析,二是完成好友的所托。

  c#静态方法和实例方法的几种用法

  见如下代码:这三种形式我们应该都用过。

    1. public class SomeClass   
    2. {   
    3. private string myfield = null;   
    4. public static instance = new SomeClass();   
    5. public instranceMethod() {};   
    6. public static staticMethod() {};   
    7. }   
    8.  public class AnotherClass   
    9.  {   
    10.  public static Main()   
    11.    {   
    12.     //第一种方式, 声明实例,调用实例方法   
    13.   SomeClass someClass = new SomeClass();   
    14.    someClass.instanceMethod();   
    15.  //第二种方式,通过一个静态的实例,去调用实例方法   
    16.   SomeClass.instance.instanceMethod();   
    17.  //第三种方式,直接调用静态方法   
    18.   SomeClass.staticMethod();   
    19.    }   
    20. }  

  这几种方式在调用时间,还有线程安全,面向对象的编程方面都有差别。后文会谈到。

  "静态方法是常驻内存"

  这是那位blog作者在评论中给出的观点。我觉得"静态方法是常驻内存"的说法是不对的。要知道一个.NET类型的静态方法是属于这个.NET类型的。而这个.NET类型是一个.NET 程序集的一部分。这个.NET程序集是被一个AppDomain装入到内存里面来的。这个AppDomain是可以从内存卸载的。一个有.NET CLR的进程里面可以有多于一个的AppDomain,第一个AppDomain之后的AppDomain都可以动态创建和卸载。这些AppDomain中的.NET程序集,既可以有静态方法,也可以有实例方法。不管是静态方法还是实例方法,都是随其程序集所在的AppDomain一起创建和卸载。第一个AppDomain在整个程序运行结束时也会最后被卸载。其中所含的.NET程序集自然也卸载。看图1会更明白点。所以静态方法不存在常驻内存一说。

  

  图1

  "静态方法比实例方法先装载"

  这也是那篇blog的评论中某些人提出的观点。我不知道他们的论据是什么,但是我已经做过实验,而且也写过这两篇blog关于.NET反射和metadata加载--致Jeffray Zhao等几位和firelong和[继续讨论]关于Windows PE和.NET assembly的加载来证明.NET程序集的加载方式是整个地加载,而不是用到某个metadata才加载该metadata, 用到某个方法才加载该方法。因为静态方法和实例方法同属于一个.NET类型,而一个.NET类型属于一个.NET程序集。在整个地加载一个.NET程序集的时候,不管是静态方法还是实例方法,都随该程序集全部加载进内存。所以"静态方法比实例方法先装载"也是不成立的。

  何时用静态方法,何时用实例方法

  先说实例方法,当你给一个类写一个方法,如果该方法需要访问某个实例的成员变量时,那么就将该方法定义成实例方法。一类的实例通常有一些成员变量,其中含有该实例的状态信息。而该方法需要改变这些状态。那么该方法需要声明成实例方法。

  静态方法正好相反,它不需要访问某个实例的成员变量,它不需要去改变某个实例的状态。我们把该方法定义成静态方法。

  第一种方式, 声明实例,调用实例方法

  当一个类有多个实例,例如学生这个类,实例可以有学生甲,学生乙,学生丙,等等,我们就用第一种方式。在多线程的情况下,只要每个线程都创建自己的实例,那么第一种方法通常是线程安全的。

  第二种方式,通过一个静态的实例,去调用实例方法

  这种情况比较特殊,通常是整个程序里该类唯一的一个实例,我们通过调用该实例的实例方法来改变该实例的某些状态。这一个实例在多线程的情况下,通常是线程不安全的。除非我们给这个实例加锁。防止其他线程访问该实例。

  第三种方式,直接调用静态方法

  这种情况下静态方法不需要去改变某个实例的状态。只要得到少量的参数就可完成既定事情。比如判断一个文件是否存在,只要给个文件路径和文件名,就能知道该文件是否存在。

 


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn

文章转载自:网络转载

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP