C# 静态方法和非静态方法
转载:http://www.cnblogs.com/mikelij/archive/2010/08/13/1798578.html
本文将围绕c#静态方法和实例方法讨论一下。针对一些观点,如:"静态方法是常驻内存", 还有"静态方法比实例方法先装载",做一个辨析。同时讨论下何时用静态方法,何时用实例方法。
前几日,在微软的好友发给我一个链接:《静态方法和实例化方法之间的区别你知道了嘛? 欢迎讨论!! - 问题最终 ...》,然后说这里某些观点需要澄清一下,希望我写一篇blog。我当时读了这篇blog. 文比较短,列举了静态方法和实例方法的几种案例,也没有论点,然后就请大家讨论。后面评论就比blog热闹多了。言辞也激烈,后来该blog作者干脆把这篇blog删了。现在已经看不到这篇blog了。现在我写这篇blog,一是针对一些观点做个辨析,二是完成好友的所托。
c#静态方法和实例方法的几种用法
见如下代码:这三种形式我们应该都用过。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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会更明白点。所以静态方法不存在常驻内存一说。

图1
"静态方法比实例方法先装载"
这也是那篇blog的评论中某些人提出的观点。我不知道他们的论据是什么,但是我已经做过实验,而且也写过这两篇blog关于.net反射和metadata加载--致Jeffray Zhao等几位和firelong和[继续讨论]关于Windows PE和.net assembly的加载来证明.net程序集的加载方式是整个地加载,而不是用到某个metadata才加载该metadata, 用到某个方法才加载该方法。因为静态方法和实例方法同属于一个.net类型,而一个.net类型属于一个.net程序集。在整个地加载一个.net程序集的时候,不管是静态方法还是实例方法,都随该程序集全部加载进内存。所以"静态方法比实例方法先装载"也是不成立的。
何时用静态方法,何时用实例方法
先说实例方法,当你给一个类写一个方法,如果该方法需要访问某个实例的成员变量时,那么就将该方法定义成实例方法。一类的实例通常有一些成员变量,其中含有该实例的状态信息。而该方法需要改变这些状态。那么该方法需要声明成实例方法。
静态方法正好相反,它不需要访问某个实例的成员变量,它不需要去改变某个实例的状态。我们把该方法定义成静态方法。
第一种方式, 声明实例,调用实例方法
当一个类有多个实例,例如学生这个类,实例可以有学生甲,学生乙,学生丙,等等,我们就用第一种方式。在多线程的情况下,只要每个线程都创建自己的实例,那么第一种方法通常是线程安全的。
第二种方式,通过一个静态的实例,去调用实例方法
这种情况比较特殊,通常是整个程序里该类唯一的一个实例,我们通过调用该实例的实例方法来改变该实例的某些状态。这一个实例在多线程的情况下,通常是线程不安全的。除非我们给这个实例加锁。防止其他线程访问该实例。
第三种方式,直接调用静态方法
这种情况下静态方法不需要去改变某个实例的状态。只要得到少量的参数就可完成既定事情。比如判断一个文件是否存在,只要给个文件路径和文件名,就能知道该文件是否存在。
学识有限,敬请您指教。
C# 静态方法和非静态方法的更多相关文章
- 转 C#中静态方法与非静态方法区别比较
C#静态方法与非静态方法的区别不仅仅是概念上的,那么他们有什么具体的区别呢?让我们通过本文向你做一下解析. C#的类中可以包含两种方法:C#静态方法与非静态方法.那么他们的定义有什么不同呢?他们在使用 ...
- 在静态方法和非静态方法上加 Synchronized的区别
Synchronzied 修饰非静态方法==>对象锁 Synchronzied 修饰静态方法==>其实是类锁,因为是静态方法,它把整个类锁起来了: 1.Synchronized修饰非静态方 ...
- C#静态类 静态方法与非静态方法比较
静态类 在类(class)上加入static修饰,表示该类无法被实例化,并将该类中,无法实例化变量或函数 静态类的主要特性 仅包含静态成员 无法实例化 静态类的本质,时一个抽象的密封类,所以不能被继承 ...
- [转]C#静态方法与非静态方法的比较
http://wenku.baidu.com/view/4e1704084a7302768e9939e0.html C#的类中可以包含两种方法:C#静态方法与非静态方法.那么他们的定义有什么不同呢?他 ...
- java中静态方法和非静态方法调用的一点小困扰,已解决。
public static void main(String[] args) { // TODO Auto-generated method stub SimpleGui1B gui=new Simp ...
- c#静态方法和非静态方法区别
c#静态方法和非静态方法区别 C#的类中可以包含两种方法:C#静态方法与非静态方法.那么他们的定义有什么不同呢?他们在使用上会有什么不同呢?让我们来看看最直观的差别:使用了static 修饰符的方法为 ...
- Java中堆、栈,静态方法和非静态方法的速度问题
一.堆和栈的速度性能分析 堆和栈是JVM内存模型中的2个重要组成部分,自己很早以前也总结过堆和栈的区别,基本都是从存储内容,存储空间大小,存储速度这几个方面来理解的,但是关于堆和栈的存储 ...
- C#中静态方法和非静态方法的区别
静态方法和非静态方法的区别: 1.静态方法不需要类实例化就可以调用,反之非静态方法需要实例化后才能调用: 2.静态方法只能访问静态成员和方法,非静态方法都可以访问: 3.静态方法不能标记为overri ...
- Java中synchronized用在静态方法和非静态方法上面的区别
synchronized 修饰在 static方法和非static方法的区别 在Java中,synchronized是用来表示同步的,我们可以synchronized来修饰一个方法.也可以sync ...
- C# 静态方法调用非静态方法
转载:http://blog.csdn.net/seattle1215/article/details/6657814 using System; using System.Collections.G ...
随机推荐
- Linux/Unix命令
MAC 中自定义环境变量 打开:nano .bash_profile 查看:cat text 保存退出:Ctrl+C,Y #在.bash_profile 中添加tree alias tree=&quo ...
- MyEclipse8.5可用注册码(到2018年)
转载自:http://blog.csdn.net/z123252520/article/details/45873159 Subscriber:zy Subscriber Code:mLR8ZC-85 ...
- HTML5基本标签、样式
感觉在Sublime Text3中写起来比较方便~~ 将HTML5中要用到的基本标签全部放在了一起,没有好好的整理,为了自己记忆的方便,就先这样写下来了~~ <!DOCTYPE html> ...
- EF-实体更新
1.数据库表增加字段,EF更新视图后,对应的实体对象没有新增的字段原因:edmx文件右键属性设置了 保存时转换相关的文本模板-false...正确的应该是rue 2. 更改视图后(或者更改字段类型?) ...
- hosts文件修改之后立刻刷新
最近因为项目的需要,总是修改hosts文件,每次修改之后都要重启浏览器,总结下刷新的方式 window下,hosts文件位置:C:\windows\system32\drivers\etc\hosts ...
- flume学习
下载 自定义sink(mysql) 1.ide打开下载后的源码 2.代码如下: /** * Licensed to the Apache Software Foundation (ASF) under ...
- PHP超全局变量
PHP提供了九种超全局变量(数组) 1 $_GET //地址栏上获得的值 2 $_POST //POST表单发送的数据 3 $_REQUEST //GET和POST的内容全都有 4 $_SERVER ...
- Android Programming: Pushing the Limits -- Chapter 5: Android User Interface Operations
多屏幕 自定义View 多屏幕 @.Android 4.2 开始支持多屏幕. @.举例: public class SecondDisplayDemo extends Activity { priva ...
- jquery学习笔记----ajax使用
一.load() 加载页面数据 load(url,[data],[callback]) url:加载的页面地址,[data]传送的数据,[callback]加载完成时回调函数. 设计一个load.ht ...
- 超好用的plsql设置
http://blog.itpub.net/24496241/viewspace-740917/