C#静态和非静态的方法2007-09-22 本站 C#的类定义中可以包含两种方法:静态和非静态的。使用了static修饰符的方法为静态方法,反之则是非静态的。静态方法是一种特殊的成员方法,它不属于类的某一个具体的实例。非静态方法可以访问类中的任何成员,而静态只能访问类中的静态成员。看这个例子:
class A{ int x; static int y; static int F(){x=1; //错误,不允许访问y=2; //正确,允许访问 }
在这个类定义中,静态方法F()可以访问类中静态成员y,但不能访问非静态成员x。这是因为,x作为非静态成员,在类的每个实例中都占有一个存储(或者说具有一个副本),而静态方法是类所共享的,它无法判断出当前的x是属于哪个类的实例,所以不知道应该到内存的哪个地址去读取当前x的值。而y是静态成员,所有类的实例都公用一个副本,静态方法F使用它就不存在什么问题。那么,是不是静态方法就无法识别类的实例了呢?在C#中,我们可以灵活地采用传递参数的办法。第十章我们提到了一个Windows窗口的例子,这里我们再对这个例子进行一些改变。程序清单11-6:
using System;class Window{ public string m_caption;//窗口的标题 public bool IsActive; //判断是否被激活 public handle m_handle; //窗口的句柄 public static int m_total; //当前打开的窗口数目 public handle Window(){m_total++; //窗口总数加1//......创建窗口的一些执行代码return m_handle; //窗口的返回值作为句柄 } ~Window(){ m_total--; //窗口总数减1 //......撤消窗口的一些执行代码 }public static string GetWindowCaption(Window w){return w.m_caption;}//......窗口的其它成员}
分析一下上面例子中的代码。每个窗口都有窗口标题m_caption、窗口句柄m_handle、窗口是否激活IsActive三个非静态的数据成员(窗口句柄是Windows操作系统中保存窗口相关信息的一种数据结构,我们在这个例子中简化了对句柄的使用)。中总共打开的窗口数目m_total作为一个静态成员。每个窗口调用构造函数创建,这时m_total的值加1。窗口关闭或因为其它行为撤消时,通过析构函数m_total的值减1.我们要注意窗口类的静态方法GetWindowCaption(Window w)。这里它通过参数w将对象传递给方法执行,这样它就可以通过具体的类的实例指明调用的对象,这时它可以访问具体实例中的成员,无论是静态成员还是非静态成员。