系统学习 学习路径总入口:先选领域,再建立模型,最后用故障演练验证

版本信息最后核对:2026-10-25

在 PowerShell 中定义带类型、构造函数和方法的类,以及配套的枚举

适用场景

当一组数据需要固定字段、输入校验和可复用行为,且会创建多个实例时,用类比散落的哈希表和函数更清晰。典型场景是模块内部的领域对象、配置模型、带状态的计算器和需要继承的扩展点。

只需要一次性传递几个字段时,[pscustomobject] 更轻量;类在解析期定义类型,不能像哈希表那样随手增删属性,跨进程和 JSON 序列化也不会保留方法。

核心概念

5.1 与 7.x 差异

常用操作

# 1. 定义枚举和类,保存为 Widget.psm1
enum WidgetState { New; Active; Retired }
class Widget {
    [string] $Name
    [WidgetState] $State
    hidden [int] $Count
    Widget([string] $name) {
        $this.Name = $name; $this.State = [WidgetState]::New; $this.Count = 0
    }
    [void] Activate() { $this.State = [WidgetState]::Active; $this.Count++ }
    [string] ToString() { return "$($this.Name):$($this.State)" }
}

# 2. run.ps1 顶部 using module,然后创建实例并调用方法
using module .\Widget.psm1
$w = [Widget]::new('api')
$w.Activate(); $w.ToString()

# 3. 属性校验与继承,子类构造函数调用 base
class ServiceWidget : Widget {
    [ValidateRange(1, 65535)] [int] $Port
    ServiceWidget([string] $name, [int] $port) : base($name) { $this.Port = $port }
    [string] Describe() { return "$($this.Name) on port $($this.Port)" }
}

# 4. 静态成员属于类型,实例可以查看真实类型
class Counter { static [int] $Total = 0; static [void] Add() { [Counter]::Total++ } }
PS C:\> [Counter]::Add(); [Counter]::Total
PS C:\> $w.GetType().FullName; $w | Get-Member

# 5. 转 JSON 只保留属性,反序列化后得到 PSCustomObject
PS C:\> $w | ConvertTo-Json
PS C:\> ('{"Name":"api"}' | ConvertFrom-Json).GetType().Name

易错点

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. 为什么 Import-Module MyModule 之后仍然找不到模块里的类?
  2. 类方法里写了一个未赋值的表达式,调用方会看到什么?
  3. ConvertTo-Json 再 ConvertFrom-Json 后,为什么不能继续调用原方法?
答案
  1. 类需要在解析阶段可见,Import-Module 是运行时加载;要在脚本或模块顶部使用 using module,并确保类定义在模块根作用域。
  2. 该表达式的结果会进入方法的输出流,调用方收到额外对象;不想返回就赋值给变量或用 [void] 丢弃。
  3. JSON 只保存公开属性,不保存类型和方法;ConvertFrom-Json 返回 PSCustomObject,方法自然不存在。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令