版本信息最后核对:2026-10-25
当一组数据需要固定字段、输入校验和可复用行为,且会创建多个实例时,用类比散落的哈希表和函数更清晰。典型场景是模块内部的领域对象、配置模型、带状态的计算器和需要继承的扩展点。
只需要一次性传递几个字段时,[pscustomobject] 更轻量;类在解析期定义类型,不能像哈希表那样随手增删属性,跨进程和 JSON 序列化也不会保留方法。
class 在解析阶段定义 .NET 类型,属性有静态类型,赋值会尝试转换;实例用 [TypeName]::new() 创建,Get-Member 能看到属性和方法。hidden 成员不出现在默认输出中,static 成员属于类型。[ValidateRange()]、[ValidateSet()] 等特性;class Child : Parent 继承属性和方法,构造函数用 : base(...) 调父类构造;enum 定义命名常量,属性用枚举类型后只能取预定义值。using module;Import-Module 只加载运行时命令,不够。class 和 enum 从 PowerShell 5.0 开始支持,5.1 可用;更老的 2.0/3.0/4.0 不支持,运行前用 #Requires -Version 5.0 声明。using module 才能让模块中的类在解析期可见,只是 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
ConvertTo-Json 只序列化公开属性,hidden 属性、方法和类型信息都会丢失;ConvertFrom-Json 得到的是 PSCustomObject,不能直接当类实例用。[void] 丢弃。Cannot redefine class。修改类定义后开新会话,或把类放在模块里重新加载。Import-Module 后报 Unable to find type,是因为类需要在解析阶段可见;改用 using module,并把它放在脚本最前面。using module 与模块导出Add-Type、语言模式和代码信任合上页面,先回答,再展开对照。
Import-Module MyModule 之后仍然找不到模块里的类?ConvertTo-Json 再 ConvertFrom-Json 后,为什么不能继续调用原方法?Import-Module 是运行时加载;要在脚本或模块顶部使用 using module,并确保类定义在模块根作用域。[void] 丢弃。ConvertFrom-Json 返回 PSCustomObject,方法自然不存在。
小程序版
微信扫码,随时查命令