如何为PowerShell集合创建类似.Where({})的自定义方法?Update-TypeData的-TypeName参数取值指引
给PowerShell集合创建自定义扩展方法(类似.Where({}))
我来帮你拆解这个问题——从搞懂.Where()的原理,到搞定Update-TypeData的类型名,再写出自己的自定义方法,一步步来:
先搞懂.Where({})到底是啥
首先得明确:.Where()不是.NET原生方法,是PowerShell通过**扩展类型系统(ETS)**给所有可枚举集合加的"外挂"方法。它的核心逻辑很简单:
- 遍历集合里的每个元素
- 把每个元素代入你传入的脚本块做判断
- 把符合条件的元素攒成新集合返回
它还支持-First/-Last这类参数,甚至能返回匹配元素的索引,灵活性拉满。
核心问题:Update-TypeData的-TypeName该填啥?
你看到的Collection1`是泛型集合的显示名,实际指定类型时有两个实用选项:
1. 让所有可枚举集合都能用(推荐)
如果想让自定义方法能作用于Get-ChildItem返回的集合、数组、List1等所有可枚举类型,直接指定System.Collections.IEnumerable`就行——因为所有能遍历的集合都实现了这个接口:
Update-TypeData -TypeName System.Collections.IEnumerable -MemberType ScriptMethod -MemberName WhereCustom -Value { param([scriptblock]$Filter) $this | Where-Object $Filter }
2. 只针对特定的Collection1`类型
要是你只想给System.Collections.ObjectModel.Collection1这个泛型类型加方法,得注意PowerShell里泛型类型的写法:泛型的符号需要用**两个反引号()**转义,所以完整的类型名是`System.Collections.ObjectModel.Collection1`:
Update-TypeData -TypeName "System.Collections.ObjectModel.Collection``1" -MemberType ScriptMethod -MemberName WhereCustom -Value { param([scriptblock]$Filter) $this | Where-Object $Filter }
完整示例:写一个自定义过滤方法
比如我们搞一个.WhereNameStartsWith()方法,专门筛选名称以指定字符串开头的元素:
# 给所有可枚举集合添加自定义方法 Update-TypeData -TypeName System.Collections.IEnumerable -MemberType ScriptMethod -MemberName WhereNameStartsWith -Value { param([string]$Prefix) # $this就是当前调用方法的集合对象 $this | Where-Object { $_.Name -like "$Prefix*" } } # 测试一下:获取文件后调用自定义方法 $gci = Get-ChildItem $gci.WhereNameStartsWith("Test")
进阶:完全模仿.Where({})的脚本块参数模式
要是想复刻.Where()的用法,支持传入脚本块当过滤条件,可以这么写:
Update-TypeData -TypeName System.Collections.IEnumerable -MemberType ScriptMethod -MemberName WhereCustom -Value { param([scriptblock]$Filter) # 遍历集合,对每个元素执行脚本块判断 $this | ForEach-Object { if (& $Filter $_) { $_ } } } # 调用测试:筛选大于1KB的文件 $gci.WhereCustom({ $_.Length -gt 1024 })
几个注意点
- 用
Update-TypeData加的类型数据只在当前PowerShell会话有效,要是想每次启动都能用,把命令加到你的PowerShell配置文件($PROFILE)里就行。 - 想查看已添加的类型数据,用
Get-TypeData命令。 - 脚本方法里的
$this是关键,它代表当前调用方法的那个集合对象。
内容的提问来源于stack exchange,提问作者Maybe
相关产品推荐
相关产品推荐

