如何捕获PowerShell类实例的点符号赋值操作以同步属性?
PowerShell时间码类属性同步解决方案
要实现直接通过点符号修改属性时同步更新所有相关属性,核心是利用PowerShell类的属性访问器(get/set),替代原来的简单公共属性定义。通过在属性的set块中触发统一的同步逻辑,就能确保任何属性修改都会联动更新其他相关属性。
实现示例
以下是改造后的Timecode类,通过私有字段存储原始数据,公共属性通过访问器控制读写并同步:
class Timecode { # 私有字段:存储底层数据,避免循环更新 hidden [int] $_frameRate hidden [int] $_totalFrames hidden [timespan] $_timeSpan # 构造函数:初始化时间码和帧率 Timecode([string]$timeStamp, [int]$frameRate) { $this._frameRate = $frameRate # 解析时间戳为总帧数和时间跨度 $parts = $timeStamp -split ':' $hours = [int]$parts[0] $minutes = [int]$parts[1] $seconds = [int]$parts[2] $frames = [int]$parts[3] $this._totalFrames = ($hours * 3600 + $minutes * 60 + $seconds) * $frameRate + $frames $this._syncFromFrameCount() } # 帧率属性:支持修改并同步 [int] get_FrameRate() { return $this._frameRate } void set_FrameRate([int]$value) { $this._frameRate = $value $this._syncFromFrameCount() } # 总帧数属性:修改时同步时间戳 [int] get_FrameCount() { return $this._totalFrames } void set_FrameCount([int]$value) { $this._totalFrames = [math]::Max(0, $value) # 避免负数帧数 $this._syncFromFrameCount() } # 秒数属性:修改时更新总帧数并同步 [int] get_Seconds() { return $this._timeSpan.TotalSeconds -as [int] } void set_Seconds([int]$value) { $currentFrames = $this._totalFrames % $this._frameRate $newTotal = ($this._timeSpan.Hours * 3600 + $this._timeSpan.Minutes * 60 + $value) * $this._frameRate + $currentFrames $this._totalFrames = $newTotal $this._syncFromFrameCount() } # 时间戳属性:基于最新数据动态生成(只读) [string] get_TimeStamp() { $totalSeconds = [math]::Floor($this._totalFrames / $this._frameRate) $hours = [math]::Floor($totalSeconds / 3600) $remaining = $totalSeconds % 3600 $minutes = [math]::Floor($remaining / 60) $seconds = $remaining % 60 $frames = $this._totalFrames % $this._frameRate return "{0:D2}:{1:D2}:{2:D2}:{3:D2}" -f $hours, $minutes, $seconds, $frames } # 私有同步方法:从总帧数更新时间跨度 hidden void _syncFromFrameCount() { $totalSeconds = [math]::Floor($this._totalFrames / $this._frameRate) $this._timeSpan = [timespan]::FromSeconds($totalSeconds) } # 原有业务方法:移除帧数 void removeFrames([int]$count) { $this._totalFrames = [math]::Max(0, $this._totalFrames - $count) $this._syncFromFrameCount() } }
关键逻辑说明
- 私有字段隔离底层数据:用
_frameRate、_totalFrames等私有字段存储实际值,避免直接操作公共属性时触发循环更新。 - 属性访问器控制读写:每个可修改的公共属性(如
Seconds、FrameCount)都定义get/set块,在set中先更新私有字段,再调用_syncFromFrameCount()同步其他属性的底层数据。 - 动态计算只读属性:
TimeStamp作为只读属性,每次获取时都基于最新的总帧数和帧率生成,确保始终准确。
测试验证
# 实例化时间码 $tc = [Timecode]::new("00:00:02:00", 12) Write-Host "初始状态:" Write-Host "TimeStamp: $($tc.TimeStamp)" Write-Host "FrameCount: $($tc.FrameCount)" Write-Host "Seconds: $($tc.Seconds)" # 直接修改秒数 $tc.Seconds = 4 Write-Host "`n修改秒数为4后:" Write-Host "TimeStamp: $($tc.TimeStamp)" Write-Host "FrameCount: $($tc.FrameCount)" Write-Host "Seconds: $($tc.Seconds)" # 调用移除帧数方法 $tc.removeFrames(12) Write-Host "`n移除12帧后:" Write-Host "TimeStamp: $($tc.TimeStamp)" Write-Host "FrameCount: $($tc.FrameCount)" Write-Host "Seconds: $($tc.Seconds)"
运行后会看到,无论是直接修改Seconds属性还是调用removeFrames方法,TimeStamp、FrameCount等属性都会同步更新。
内容的提问来源于stack exchange,提问作者Ralf_Reddings
相关产品推荐
相关产品推荐

