关于c#静态方法和实例方法的辨析和应用

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

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

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

public class SomeClass

{

private string myfield = null;

public static instance = new SomeClass();

public instranceMethod() {};

public static staticMethod() {};

}

public class AnotherClass

{

public static 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程序集的时候,不管是静态方法还是实例方法,都随该程序集全部加载进内存。所以"静态方法比实例方法先装载"也是不成立的。

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

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

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

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

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

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

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

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

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

  学识有限,敬请您指教。

时间: 2024-09-17 04:30:10

关于c#静态方法和实例方法的辨析和应用的相关文章

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

本文将围绕c#静态方法和实例方法讨论一下.针对一些观点,如:"静态方法是常驻内存", 还有"静态方法比实例方法先装载",做一个辨析.同时讨论下何时用静态方法,何时用实例方法. 前几日,在微软的好友发给我一个链接:<静态方法和实例化方法之间的区别你知道了嘛? 欢迎讨论!! - 问题最终 ...>,然后说这里某些观点需要澄清一下,希望我写一篇blog.我当时读了这篇blog. 文比较短,列举了静态方法和实例方法的几种案例,也没有论点,然后就请大家讨论.后面评

java静态方法和实例方法的区别

静态方法和实例方法的区别主要体现在两个方面: 在外部调用静态方法时,可以使用"类名. 方法名"的方式,也可以使用"对象名.方法名"的方式.而实例方法只有后面这种方式.也就 是说,调用静态方法可以无需创建对象. 静态方法在访问本类的成员时,只允许访问静态成员(即静 态成员变量和静态方法),而不允许访问实例成员变量和实例方法:实例方法则无此限制. 下面几个 例子展示了这一区别. 1.调用静态方法示例. //-----------hasStaticMethod.java-

Objective-C 关于静态方法与实例方法的转载

Objective-C 关于静态方法与实例方法的转载 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 转载1: http://www.cocoachina.com/bbs/read.php?ti

Js类的静态方法与实例方法区分及jQuery拓展的两种方法_javascript技巧

上学时C#老师讲到对象有两类方法,静态方法(Static)和实例方法(非Static),当时不理解静态是为何意,只是强记. 后来从事了前端的工作,一直在对类(即对象,Js中严格来说没有类的定义,虽众所周知,这里还是赘述一番,以免产生歧义)的操作上,严重缺乏整体概念,最近看extetnd中再次提到拓展静态方法与实例方法,故而再次百度,才幡然领悟,其实一直有用,只是不知其专业术语呀,哈哈~ 静态方法,属于类的方法,即类可以直接调用的方法.为类所有实例化对象所共用(但不能用实例对象之间调用),所以静态

关于静态方法和实例方法的一些误区。

转自<关于静态方法和实例方法的一些误区.> 一. 静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存.     事实上,方法都是一样的,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载.调用的速度基本上没有差别. 二. 静态方法在堆上分配内存,实例方法在堆栈上.     事实上所有的方法都不可能在堆或者堆栈上分配内存,方法作为代码是被加载到特殊的代码内存区域,这个内存区域是不可写的. 三. 实例方法需要先创建实例才可以调用,比较麻烦,静态方法不用,比较简单.

js静态方法与实例方法分析_javascript技巧

js静态方法 复制代码 代码如下: function foo(){} // 声明类 foo.method = function(){} // 方法体 使用:foo.method() js实例方法 function foo(){ // 声明类 this.method = function(){ // 方法体 } } 使用:var f = new foo(); f.method();

在何种情况下,使用静态方法和实例方法?

问题描述 在什么情况下,使用静态方法?在情况下,使用实例方法? 解决方案 解决方案二:静态方法:对实例没有访问要求的时候用,属于这个类的类方法.实例方法:使用时必须创建这个对象.也就是要用到对象中方法的时候,反之,本类中的方法将来会被其它类调用的时候.也叫作对象方法.解决方案三:看情况了,项目中一些共通的部分,比如读取配置,写LOG,可以用静态方法.操作比较简单.如果是一个对象要多次被处理,考虑使用实例方法比如.NET中对文件操作有静态的File类和FileInfo类前面都是静态方法,后面是实例

JNI/NDK开发指南(六)——C/C++访问Java实例方法和静态方法

        转载请注明出处:http://blog.csdn.net/xyang81/article/details/42582213         通过前面5章的学习,我们知道了如何通过JNI函数来访问JVM中的基本数据类型.字符串和数组这些数据类型.下一步我们来学习本地代码如何与JVM中任意对象的属性和方法进行交互.比如本地代码调用Java层某个对象的方法或属性,也就是通常我们所说的来自C/C++层本地函数的callback(回调).这个知识点分2篇文章分别介绍,本篇先介绍方法回调,在

静态和实例方法区别-java

静态方法和实例方法的区别主要体现在两个方面:   在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式.而实例方法只有后面这种方式.也就是说,调用静态方法可以无需创建对象.   静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法:实例方法则无此限制.   下面几个例子展示了这一区别.   1.调用静态方法示例.   //-----------hasStaticMethod