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

PowerShell中如何扩展集合类并覆写Add方法

背景

我在PowerShell中有一个包含4个属性的数据对象,其中3个为字符串类型,第4个为Hashtable类型。我希望定义一种新类型,作为该数据对象的集合。

在这个集合类中,我希望强制执行特定格式,以便模块中的其他代码更易用。具体来说,我希望覆写Add方法,使得当3个字符串属性的组合唯一时,添加第4个哈希表属性;而当组合重复时,仅用新输入的哈希表更新已有行的哈希表属性。

这样可以抽象集合的扩展逻辑,确保调用Add方法时,集合始终保持按3个字符串属性的唯一组合分组哈希表的格式。

我的思路是创建一个继承自集合的类,然后覆写Add方法。

现有代码

以下代码包含3个类:

  • 一个基于3个字符串属性的命名空间数据类(可在脚本中复用)。
  • 一个为该数据类添加id属性的类,id是哈希表的键,对应的值为对象命名空间中的配置参数。
  • 一个处理上述对象集合的类,用于定义Add方法。这是我遇到问题的地方。
Using namespace System.Collections.Generic

Class Model_Namespace {
    [string]$Unit
    [string]$Date
    [string]$Name

    Model_Namespace([string]$unit, [string]$date, [string]$name) {
        $this.Unit = $unit
        $this.Date = $date
        $this.Name = $name
    }
}

Class Model_Config {
    [Model_Namespace]$namespace
    [Hashtable]$id
    
    Model_Config([Model_Namespace]$namespace, [hashtable]$config) {
        $this.namespace = $namespace
        $this.id = $config
    }
    Model_Config([string]$unit, [string]$date, [string]$name, [hashtable]$config) {
        $this.namespace = [Model_Namespace]::new($unit, $date, $name)
        $this.id = $config
    }
}

Class Collection_Configs {
    $List = [List[Model_Config]]@()

    [void] Add ([Model_Config]$newConfig ){
        $checkNamespaceExists = $null

        $u  = $newConfig.Unit
        $d  = $newConfig.Date
        $n  = $newConfig.Name
        $id = $newConfig.id

        $checkNamespaceExists = $this.List | Where { $u -eq $_.Unit -and $d -eq $_.Date -and $n -eq $_.Name }

        If ($checkNamespaceExists){
            ($this.List | Where { $u -eq $_.Unit -and $d -eq $_.Date -and $n -eq $_.Name }).id += $id
        }
        Else {
            $this.List.add($newConfig)
        }
    }
}

问题

我希望Collection_Configs类继承自内置集合类型并覆写Add方法。像泛型List<>类型一样,直接输出集合变量即可返回集合,无需通过List属性访问集合,甚至不需要List属性。

但继承System.Array时需要在构造函数中指定固定数组大小,而我的集合需要是可变的,因此希望避免这种方式。我尝试继承List,但语法无法生效,PowerShell抛出类型未找到的错误。

是否有办法实现这一需求?

更新

在mklement的帮助下,我修改了最后一个类:

Using namespace System.Collections.ObjectModel

Class Collection_Configs : System.Collections.ObjectModel.Collection[Object]{

    [void] Add ([Model_Config]$newConfig ){
        $checkNamespaceExists = $null

        $newConfigParams = $newConfig.namespace
        $u  = $newConfigParams.Unit
        $d  = $newConfigParams.Date
        $n  = $newConfigParams.Name
        $id = $newConfig.id

        $checkNamespaceExists = $this.namespace | Where { $u -eq $_.Unit -and $d -eq $_.Date -and $n -eq $_.Name }

        If ($checkNamespaceExists){
            ($this | Where { $u -eq $_.namespace.Unit -and $d -eq $_.namespace.Date -and $n -eq $_.namespace.Name }).id += $id
        }
        Else {
            ([Collection[object]]$this).add($newConfig)
        }
    }
}

该代码似乎可以运行。除了继承外,我还修正了访问输入类型的方式,并且需要在其他两个类之后单独加载集合类,同时在else语句中调用基类的Add方法。

接下来我需要进行其他验证,确保仅能输入Model_Config类型。目前自定义集合接受任何输入,即使我将Add方法的参数转换为Model_Config类型,例如:

$config = [model_config]::new('a','b','c',@{'h'='t'})
$collection = [Collection_Configs]::new()
$collection.Add($config)

可以正常运行,但:

$collection.Add('test')

也能运行,这是不符合预期的。可能是因为没有正确覆写方法,而是调用了基类的重载?

最终更新

现在所有功能都正常了。最后更新的类代码如下:

using namespace System.Collections.ObjectModel

Class Collection_Configs : Collection[Model_Config]{

    [void] Add ([Model_Config]$newConfig ){
        $checkNamespaceExists = $null
        
        $namespace = $newConfig.namespace
        $u  = $namespace.Unit
        $d  = $namespace.Date
        $n  = $namespace.Name
        $id = $newConfig.id

        $checkNamespaceExists = $this.namespace | Where { $u -eq $_.Unit -and $d -eq $_.Date -and $n -eq $_.Name }

        If ($checkNamespaceExists){
            ($this | Where { $u -eq $_.namespace.Unit -and $d -eq $_.namespace.Date -and $n -eq $_.namespace.Name }).id += $id
        }
        Else {
            [Collection[Model_Config]].GetMethod('Add').Invoke($this, [Model_Config[]]$newConfig)
        }
    }
}

注意,else语句中的....GetMethod('Add')...在Windows PowerShell中是必需的,这是mklement0的回答中提到的。如果使用PowerShell Core,则可以使用mklement0提供的语法(我已测试通过)。

mklement0还提到,类型需要单独加载。在命令行快速测试时,可以先输入Model_Namespace和Model_Config类并回车,再输入Collection_Configs类并回车。

综上,该方案可在PowerShell中创建带自定义方法的自定义集合类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 05:45:22