Show/Hide Toolbars

XSharp

PARTIAL

在类声明中使用 PARTIAL 修饰符可指示编译器,类定义及其成员(方法、属性等)可能会跨当前应用程序/库中的多个程序文件。默认情况下(不使用 PARTIAL 修饰符时),类的所有成员都应在单个文件中定义,如果它们跨多个文件,则该类的所有 CLASS...END CLASS 定义都需要标记为 PARTIAL:

// file code1.prg
PARTIAL CLASS ClassSpanningInMultipleFiles // 省略 PARTIAL 会导致编译器错误,因为在类型声明中缺少部分修饰符。
  METHOD MethodInFile1() AS VOID
END CLASS
 
// file code2.prg
PARTIAL CLASS ClassSpanningInMultipleFiles
  PROPERTY PropertyInFile2() AS LOGIC
    GET
        RETURN TRUE
    END GET
  END PROPERTY
END CLASS

请注意,部分类的所有成员必须在同一个程序集中定义。不能使用 PARTIAL 修饰符在不同的程序集/库中定义类的成员。

 

EXTERN

EXTERN 修饰符告诉编译器某个方法是在外部实现的,因此它在代码本身中没有主体。EXTERN 通常与 DllImport 属性(System.Runtime.InteropServices.DllImportAttribute)一起使用,后者指定了方法的具体实现位置(通常在 Win32 API dll 中)和调用方式。使用该属性时,还需要将方法声明为静态方法:

USING System.Runtime.InteropServices
FUNCTION Start() AS VOID
  WinAPICalls.MessageBox(IntPtr.Zero, "通过 EXTERN 方法调用非托管代码", "EXTERN 修饰符示例", 0)
 
STATIC CLASS WinAPICalls
  [DllImport("user32.dll", CharSet := CharSet.Unicode)];
  STATIC EXTERN METHOD MessageBox(hWnd AS IntPtr, text AS STRING , caption AS STRING , type AS DWORD ) AS INT
END CLASS

请注意,EXTERN 方法直接返回值是编译器错误,因为它的完整实现是由外部提供的。

UNSAFE

方法上的 UNSAFE 修饰符指定其整个主体将在不安全上下文中运行,这意味着它可以使用指向数据的指针并直接操作内存。只有启用编译器选项允许不安全代码(/unsafe)后,才能使用不安全修改器:

FUNCTION Start() AS VOID
  ? UnsafeMethods.GetByte2of4(0x10203040) // 32 (hex 20)
 
CLASS UnsafeMethods
  UNSAFE STATIC METHOD GetByte2of4(d AS DWORD) AS BYTE
    LOCAL p AS BYTE PTR
     p := (BYTE PTR) @d //获取直接指向数据的指针
    RETURN p[3]
END CLASS

当方法体中只有一小部分涉及指针或其他潜在的不安全操作时,更常见的做法是为其声明一个 BEGIN UNSAFE 块,而不是将整个方法标记为不安全:

CLASS UnsafeMethods
  STATIC METHOD GetByte2of4(d AS DWORD) AS BYTE
    LOCAL b AS BYTE
     ? "Begin of unsafe possibly code executing"
     
    BEGIN UNSAFE // 该代码块内的代码使用指针操作
        LOCAL p AS BYTE PTR
        p := (BYTE PTR) @d // 获取直接指向数据的指针
        b := p[3]
    END UNSAFE
     ? "End of unsafe code"
 
    RETURN b
END CLASS

请注意,我们强烈反对编写使用指针的代码(因为.Net 运行时无法验证代码的正确使用,而且会破坏运行应用程序的稳定性),只有在绝对必要的情况下,才需要极其谨慎地使用指针。