PowerShell动态构建版本列表并匹配指定版本范围的技术咨询
版本范围匹配代码的动态初始化验证
我之前提交过类似问题,现在需要修改代码实现新需求:从存储所有可能版本的对象$results中动态构建[List[]]$versions(替代手动初始化),使脚本返回指定版本范围内的所有版本(包含边界,如范围8.6.22-8.6.32需返回8.6.22、8.6.32)。我已做修改但不确定逻辑是否合理,特寻求验证,代码如下:
[List[]] $versions = $results # Initialize the array of [Lab] objects. [List[]] $versions = [List]::new('8.6.22'), [List]::new('8.6.32'), [List]::new('8.6.13'), [List]::new('8.6.40'), [List]::new('8.6.41'), [List]::new('8.6.51') # Initialize a version-range evaluator, here with a single range. $rangeEvaluator = [LabVersionRangeEvaluator]::new(@('8.6.22-8.6.60')) $list = $rangeEvaluator.GetMatchingLabs($versions).version -join ',' $list # --- Class definitions # A single lab. class List { # Properties [version] $Version # Constructor List([string] $version) { $this.Version = $version } } class LabVersionRangeEvaluator { # Properties: The endpoints for the stored version ranges. [version[]] $start [version[]] $end # Constructor LabVersionRangeEvaluator([string[]] $ranges) { $this.start = [version[]]::new($ranges.Count) $this.end = [version[]]::new($ranges.Count) [int[]] $components = $null $i = 0 foreach ($range in $ranges) { $pass = 0 $vers = $range -split '-', 2 if ($vers.Count -eq 1) { $vers += $vers[0] } foreach ($pass in 0..1) { $components = $vers[$pass] -split '\.' if ($pass -eq 0) { # Trim trailing .0 components so as to make them -1 in the resulting # [version] instance, so that something like 8.6 >= 8.6.0 works. # (Note that [version] '8.6' -ge [version] '8.6.0' returns $false, # due to the internal -1 components for .Build and .Revision in # [version] '8.6') $j = $components.Count while ($components[--$j] -eq 0) { } $this.start[$i] = [version]::new.Invoke([object[]] $components[0..$j]) } else { # Fill in the unspecified components with [int]::MaxValue $components += (, [int]::MaxValue) * (4 - $components.Count) $this.end[$i] = [version]::new.Invoke([object[]] $components) } } ++$i } } # Given a list of labs, return the sublist that falls into the stored range(s). [List[]] GetMatchingLabs([List[]] $versions) { $results = [System.Collections.Generic.List[List]]::new() :next_lab foreach ($ver in $versions) { foreach ($i in 0..($this.start.Count - 1)) { if ($ver.Version -ge $this.start[$i] -and $ver.Version -le $this.end[$i]) { $results.Add($ver) continue next_lab } } } return $results.ToArray() } }
核心问题解答:[List[]] $versions = $results 是否可行
这取决于$results的实际类型:
- 如果
$results本身就是**[List]类型对象的数组/集合**,直接赋值完全可行,因为类型匹配,[List[]]会自动将集合转换为强类型数组。 - 如果
$results是字符串格式的版本号集合,直接赋值会报错(类型不匹配),需要先将每个字符串转换为[List]对象,示例代码:[List[]]$versions = $results | ForEach-Object { [List]::new($_) }
代码其他注意点
- 类名冲突问题:自定义类命名为
List会和.NET内置的System.Collections.Generic.List<T>重名,容易造成混淆和潜在bug,建议改为更具语义的名字(比如LabVersion)。 - 变量覆盖问题:当前代码中手动初始化的
[List[]] $versions会覆盖前面的[List[]] $versions = $results,实际运行时只会使用手动初始化的版本列表,若要测试动态初始化逻辑,需注释掉手动初始化的代码段。 - 范围匹配逻辑验证:代码中使用
$ver.Version -ge $this.start[$i] -and $ver.Version -le $this.end[$i]的判断逻辑完全符合需求,能够正确包含范围的边界值。 - 版本处理逻辑合理性:构造函数中对起始版本去除末尾
.0、对结束版本补全未指定组件为[int]::MaxValue的逻辑,能够兼容不同格式的版本范围(如8.6-8.6.60这类简写范围),是合理的。
内容的提问来源于stack exchange,提问作者Bandit
相关产品推荐
相关产品推荐

