Show/Hide Toolbars

XSharp

 

当 STATIC 修饰符用于类或其成员、FUNCTION/GLOBAL 或 LOCAL 变量时,其含义有所不同。

静态类和静态成员

静态成员

类成员(方法、构造函数、属性、字段、事件)上的 STATIC 修饰符所声明的成员属于类本身,而不是类的实例。普通(实例)方法和其他成员可以通过使用冒号(“:”)运算符(如果编译器选项 /allowdot 启用,也可以使用点“. ”运算符)调用类的实例(例如通过 SELF 或容纳实例对象的局部变量),而静态成员则可以通过使用点运算符直接访问类本身:

FUNCTION Start() AS VOID
  LOCAL oInstance AS TestClass
  oInstance := TestClass{}
 
  ? oInstance:instance_field
  ? oInstance:InstanceMethod()
  ? oInstance:InstanceProperty
 
  ? TestClass.static_field
  ? TestClass.StaticMethod()
  ? TestClass.StaticProperty

CLASS TestClass
  EXPORT instance_field := "instance field" AS STRING
  STATIC EXPORT static_field := "static field" AS STRING
 
  METHOD InstanceMethod() AS STRING
  RETURN "Instance method"
  PROPERTY InstanceProperty() AS STRING GET "Instance property"
     
  STATIC METHOD StaticMethod() AS STRING
  RETURN "Static method"
  STATIC PROPERTY StaticProperty() AS STRING GET "Instance property"
END CLASS

静态方法与普通函数非常相似,可以以同样的方式使用,但静态方法的优势在于它被封装在一个类中,而这个类可能包含其他相关的静态或非静态成员。与函数一样,静态方法不能使用类中带有 SELF: 的实例成员,但可以访问其他静态成员。具有相关功能的方法可以集中在同一个类中,从而在编辑器中提供更好的智能感应支持(在类名后键入一个点将显示其所有静态成员的列表),并使代码更有条理。例如,System.Math 类提供了大量的数学函数,这些函数都集中在一个类中,这样就更容易查找和使用,而不是由几个独立的函数来提供相同的功能。同样,静态字段也可以被视为一个 GLOBAL,但同样是在一个类下进行结构化。一个类中的任何方法,如果没有在其主体中使用 SELF(因此没有访问任何实例成员),都可以声明为静态方法。

静态构造函数

也可以为每个类定义一个静态构造函数,保证在首次访问该类的任何静态成员(方法、字段等)之前自动调用该构造函数。静态构造函数必须没有参数,并且不能重载。静态构造函数的典型用途是初始化静态字段:

FUNCTION Start() AS VOID
  ? TestClass.static_field // 由静态构造函数调整
 
CLASS TestClass
  STATIC EXPORT static_field := "初始值" AS STRING
 
  STATIC CONSTRUCTOR()
     ? TestClass.static_field // 初始值
     TestClass.static_field := "由静态构造函数调整"
END CLASS

请注意,不允许定义静态析构函数。如果需要清理存储在静态类中的数据,建议在 AppDomain 类中注册 ProcessExit 事件处理程序。

FUNCTION Start() AS VOID
 
CLASS TestClass
 
  STATIC CONSTRUCTOR()
     AppDomain.CurrentDomain:ProcessExit += EventHandler{CurrentDomain_ProcessExit}
 
static method CurrentDomain_ProcessExit(sender as object, e as EventArgs) as void
  // 清理
  return
END CLASS

静态类

当设计一个类只包含静态成员时,可以将其自身声明为静态。这样,编译器就可以检查类中的每个成员,确保没有一个成员被意外声明为非静态成员:

STATIC CLASS StaticClass
  STATIC EXPORT static_field AS STRING
  EXPORT accidental_instance AS STRING // 编译器错误 XS0708:无法在静态类中声明实例成员
 
  STATIC METHOD Static_method() AS VOID
  METHOD Accidental_Instance_method() AS VOID // 编译器错误 XS0708:无法在静态类中声明实例成员
END CLASS

静态函数和全局(GLOBAL)

将函数或全局项声明为 static 时,其可见性仅限于声明该函数或全局项的代码文件。这样,多个文件可以声明同名的函数和全局,但每个函数和全局只能在各自的文件中可见:

STATIC GLOBAL GlobalVisibleOnlyInThisFile AS INT
STATIC FUNCTION FunctionVisibleOnlyInThisFile() AS VOID

静态局部(变量)

将局部变量声明为 STATIC(静态)后,只有在首次调用方法、函数或其他实体时,才会对其进行一次初始化。在下一次调用代码时,局部变量将保留其先前的值:

FUNCTION Start() AS VOID
  ? TestStaticLocal() // 2
  ? TestStaticLocal() // 3
  ? TestStaticLocal() // 4
 
FUNCTION TestStaticLocal() AS INT
  STATIC LOCAL nStaticLocal := 1 AS INT // 只有在第一次调用函数时才会被初始化为 1
  nStaticLocal ++ // 下次调用函数时将保留当前值
RETURN nStaticLocal