You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为PSCustomObject添加多个ScriptMethods导致方法调用重复执行

问题根源与解决办法

你的代码中每个ScriptMethod调用都会执行多次,核心原因是**Add-Member的-PassThru参数使用不当,导致函数返回了多个对象**:

  • Add-Member默认会直接修改输入的对象,不需要返回结果;加上-PassThru参数后,它会把修改后的对象输出到管道中。
  • 你的函数没有明确的return语句,PowerShell会自动将所有管道输出的内容作为函数返回值。三次Add-Member调用就输出了三个修改后的对象,因此$LocalCustomObject实际是一个包含3个对象的数组。
  • 当你对数组调用方法时,PowerShell会自动遍历数组中的每个对象执行该方法,这就是为什么每个方法的执行次数等于ScriptMethod的添加数量。

解决方法1:移除-PassThru参数(推荐)

既然Add-Member会直接修改原对象,完全不需要-PassThru参数,直接删除即可:

function GetCustomObject {
    
    param(
        [Parameter(Mandatory=$true)] [String]$data
    )
    
    $CustomObject = [PSCustomObject]@{
        member = $data
    }

    $CustomObject | Add-Member -MemberType ScriptMethod -Name PrintMember -Value {
        Write-Host "Data is:" $this.member
        $this.member += ", again?"
    }

    $CustomObject | Add-Member -MemberType ScriptMethod -Name SomeOtherFunction -Value {
        Write-Host "SomeOtherFunction"
    }

    $CustomObject | Add-Member -MemberType ScriptMethod -Name YetAnotherFunction -Value {
        Write-Host "YetAnotherFunction"
    }

    # 明确返回单个自定义对象
    return $CustomObject
}


$LocalCustomObject = GetCustomObject "Hello World"

$LocalCustomObject.PrintMember()
# 输出:Data is: Hello World

$LocalCustomObject.SomeOtherFunction()
# 输出:SomeOtherFunction

$LocalCustomObject.YetAnotherFunction()
# 输出:YetAnotherFunction

解决方法2:捕获-PassThru的输出(仅适合特殊场景)

如果必须使用-PassThru,需要将每次的输出赋值回$CustomObject,避免多余的管道输出:

function GetCustomObject {
    
    param(
        [Parameter(Mandatory=$true)] [String]$data
    )
    
    $CustomObject = [PSCustomObject]@{
        member = $data
    }

    # 将返回的对象赋值回变量,防止输出到管道
    $CustomObject = $CustomObject | Add-Member -MemberType ScriptMethod -PassThru -Name PrintMember -Value {
        Write-Host "Data is:" $this.member
        $this.member += ", again?"
    }

    $CustomObject = $CustomObject | Add-Member -MemberType ScriptMethod -PassThru -Name SomeOtherFunction -Value {
        Write-Host "SomeOtherFunction"
    }

    $CustomObject = $CustomObject | Add-Member -MemberType ScriptMethod -PassThru -Name YetAnotherFunction -Value {
        Write-Host "YetAnotherFunction"
    }

    return $CustomObject
}

更优雅的写法:使用PowerShell类(PS5.0+)

如果你的PowerShell版本支持5.0及以上,直接定义类会更清晰,避免手动添加成员的繁琐操作:

class CustomObject {
    [string]$member

    # 构造函数
    CustomObject([string]$data) {
        $this.member = $data
    }

    [void] PrintMember() {
        Write-Host "Data is:" $this.member
        $this.member += ", again?"
    }

    [void] SomeOtherFunction() {
        Write-Host "SomeOtherFunction"
    }

    [void] YetAnotherFunction() {
        Write-Host "YetAnotherFunction"
    }
}

# 创建对象实例
$LocalCustomObject = [CustomObject]::new("Hello World")

$LocalCustomObject.PrintMember()
$LocalCustomObject.SomeOtherFunction()
$LocalCustomObject.YetAnotherFunction()

内容的提问来源于stack exchange,提问作者Alex Apel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:50:33