posts - 16, comments - 68, trackbacks - 8, articles - 0

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

Posted on 2006-06-30 11:10 Ivony... 阅读(867) 评论(6)  编辑 收藏 所属分类: .NET
一、    静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存。
 
    事实上,方法都是一样的,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。
 
 
二、    静态方法在堆上分配内存,实例方法在堆栈上。
 
    事实上所有的方法都不可能在堆或者堆栈上分配内存,方法作为代码是被加载到特殊的代码内存区域,这个内存区域是不可写的。
 
 
三、    实例方法需要先创建实例才可以调用,比较麻烦,静态方法不用,比较简单。
    事实上如果一个方法与他所在类型的实例无关,那么它就应该是静态的,决不会有人把它写成实例方法。所以所有的实例方法都与实例有关,既然与实例有关,那么创建实例就是必然的步骤,没有麻烦简单一说。实际上上你可以把所有的实例方法都写成静态的,将实例作为参数传入即可。
    有些方法看似与所在的实例无关,如IComparer.Compare方法,但实际上每一个实现这个接口的类都只会负责自己类型实例的比较,这是C#1.x规范中没有泛型所带来的历史遗留问题。
    大部分静态方法是与类的实例有关的,如各种Parse方法,他做成静态的原因是他没有实例作为参数。其他的大多是出于语义或者其他目的的考虑。
 
 

Feedback

#1楼    回复  引用  查看    

2006-07-17 16:26 by WinkSky      
事实上如果一个方法与他所在类型的实例无关,那么它就应该是静态的,决不会有人把它写成实例方法。

请问此句何解,不是很了解。什么叫一个方法与他所在类型的实例无关?

#2楼    回复  引用    

2006-07-25 11:03 by richzhao [未注册用户]
是否可以这样理解:
与实例无关且常被使用的方法适合写成静态方法。

#3楼 [楼主]   回复  引用  查看    

2006-07-25 11:10 by Ivony...      
没有经常被使用一说。

与实例无关可以参看Math类,他根本就没有实例,所以所有的方法也都是与实例无关的。

其次还有HttpUtility类,同样也是没有实例的。


那么有实例但又确实与实例无关的静态方法也能在.NET Framework中找到,如Regex的静态方法。其实,因为.NET Framework面向对象的程度非常高,所以与实例无关的方法其实很难找。

#4楼    回复  引用  查看    

2007-09-06 10:00 by ji yang      
Ivony,你好:
我们项目中也碰到了这个问题,有人认为类的静态方法会占用资源,要求都做成实例方法,随用随New, 随释放。

我个人觉得类的静态方法使用起来其实更直观,而且微软的很多类也是这种形式。并且,在VS2005中运行代码分析,对于以下的 Foo方法也会建议你修改为静态方法:
class People
{
public void Foo()
{

}
}

警告CA1822 : Microsoft.Performance : 从未使用 People.Foo():Void 的“this”参数。根据需要,将成员标记为 static ,或者在方法体或至少一个属性访问器中使用“this”/“Me”。

MSDN中也有说明:
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VSENT.v80.chs/dv_vsetsa03/html/743f0af7-41d1-4852-8d97-af0688b31118.htm
可以将不访问实例数据或调用实例方法的方法标记为 static。在将这些方法标记为 static 之后,编译器将向这些成员发出非虚拟调用站点。发出非虚拟调用站点将禁止在运行时对每个调用进行检查,从而确保当前的对象指针为非空。这会使性能敏感的代码的性能得到显著提高。在某些情况下,如果无法访问当前的对象实例,则表示存在正确性问题。

这儿的意思是,如果标记为静态方法后,调用时将省去检查实例是否为null这一步骤,使得多次调用的方法速度更快。

那么我想问一下,静态方法的加载与释放,你是否有更详细的说明,或告知资料来源?即,静态方法,实例方法的加载释放过程的区别?

非常感谢 :)





#5楼 [楼主]   回复  引用  查看    

2007-09-06 17:43 by Ivony...      
关于方法的加载,你可以参考程序集加载的相关资料,方法分为两部分,代码和元数据。


不过你只要弄清楚,静态方法和实例方法没有本质上的不同就行了,实例方法实际上就是多了一个隐藏参数this的方法。

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2006-06-30 13:28 编辑过


相关链接: