【问题标题】:Is it possible to attach an event to a PSObject?是否可以将事件附加到 PSObject?
【发布时间】:2013-09-18 06:54:45
【问题描述】:

假设我有一个这样的 psobject:

$o=New-Object PSObject -Property @{"value"=0}
Add-Member -MemberType ScriptMethod -Name "Sqrt" -Value {
    echo "the square root of $($this.value) is $([Math]::Round([Math]::Sqrt($this.value),2))"
} -inputObject $o

是否可以附加一个事件,以便在 value 属性更改时执行方法 Sqrt() ?即:

PS>$o.value=9

会产生

the square root of 9 is 3

更新

根据@Richard 的回答,这是有效的配方:

$o=New-Object PSObject -property @{"_val"=1}
Add-Member -MemberType ScriptMethod -Name "Sqrt" -Value {
    write-host "the square root of $($this._val) is $([Math]::Round([Math]::Sqrt($this._val),2))"
} -inputObject $o


Add-Member -MemberType ScriptProperty -Name 'val' -Value{ $this._val }  -SecondValue { $this._val=$args[0];$this.Sqrt() } -inputObject $o

【问题讨论】:

    标签: events powershell powershell-3.0 psobject


    【解决方案1】:

    与其将value 设为NoteProperty,不如将​​其设为ScriptProperty,这包括定义单独的get 和set 方法,这些方法被调用而不是直接修改字段。

    $theObject | Add-Member -MemberType ScriptProperty -Name 'Value' 
                            -Value{ $this._value }
                            -SecondValue { $this._value = $args[0]; $this.Sqrt }
    

    Value定义get方法,SecondValueset。)

    注意,由于 PowerShell 不提供任何封装数据的功能,调用者仍然可以访问底层字段。用 C#(或其他 .NET 语言)编写自定义类型并使用 Add-Type 可以避免这种情况,但不太值得这样做,除非您确实有不遵守规则的调用者。

    第二期

    在 ScriptProperty 中没有输出管道(任何输出都被丢弃),因此 echo(作为 Write-Output 的别名)不会做任何有用的事情。用Write-Host 替换它可以工作。一般来说,属性 get 或 set(包括输出)中的副作用是不好的做法(使用它们时期望低开销)。

    【讨论】:

    • 您已经根据自身定义了val。基础字段必须是不同的名称(注意我使用的 _ 前缀)。
    • 哎呀,谢谢。但是,现在基础字段已修改但方法未执行。我已经更新了我的帖子。
    • 你的意思是这是一种不好的做法吗?
    • @Kayasax:使用属性来产生副作用:是的。 (但是我会说“差”而不是“坏”:那里有更糟糕的做法:-(。)
    • 好的。但在这种情况下,它将是故意的(我在考虑类似 onChange 或 onSubmit 事件在 javascript 中)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    相关资源
    最近更新 更多