• 【转】一起谈.NET技术,关于c#静态方法和实例方法的辨析和应用


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

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

      c#静态方法和实例方法的几种用法,见如下代码:这三种形式我们应该都用过。

    publicclass SomeClass
    {
    privatestring myfield =null;
    publicstatic instance =new SomeClass();
    public instranceMethod() {};
    publicstatic staticMethod() {};
    }

    publicclass AnotherClass
    {
    publicstatic Main()
    {
    //第一种方式, 声明实例,调用实例方法
    SomeClass someClass =new SomeClass();
    someClass.instanceMethod();

    //第二种方式,通过一个静态的实例,去调用实例方法
    SomeClass.instance.instanceMethod();

    //第三种方式,直接调用静态方法
    SomeClass.staticMethod();
    }
    }

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

      "静态方法是常驻内存"

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

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

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

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

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

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

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

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

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

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

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

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

      学识有限,敬请您指教。

    转自:http://www.cnblogs.com/waw/archive/2011/08/29/2158617.html

  • 相关阅读:
    HDU 2544 最短路
    HDU 3367 Pseudoforest
    USACO 2001 OPEN
    HDU 3371 Connect the Cities
    HDU 1301 Jungle Roads
    HDU 1879 继续畅通工程
    HDU 1233 还是畅通工程
    HDU 1162 Eddy's picture
    HDU 5745 La Vie en rose
    HDU 5744 Keep On Movin
  • 原文地址:https://www.cnblogs.com/zhangzheny/p/2238816.html
Copyright © 2020-2023  润新知