如何创建自定义Powershell操作符?
是否可以在Powershell中创建自定义运算符?我该怎么做呢?我搜索过谷歌,但什么都没找到 我指的是中缀操作符: $ExampleList-包含“元素”如何创建自定义Powershell操作符?,powershell,customization,Powershell,Customization,是否可以在Powershell中创建自定义运算符?我该怎么做呢?我搜索过谷歌,但什么都没找到 我指的是中缀操作符: $ExampleList-包含“元素” 我已经创建了cmdlet(使用Powershell和C#)、模块等,所以我只需要大致的笔划。您可以创建一个cmdlet并将列表导入其中。 要评估列表,请确保使用结束功能,而不是过程。 Process将自动迭代该集合,您不希望在此处重复该集合 您的脚本将如下所示: $ExampleList | Test-Contains "element"
我已经创建了cmdlet(使用Powershell和C#)、模块等,所以我只需要大致的笔划。您可以创建一个cmdlet并将列表导入其中。 要评估列表,请确保使用
结束
功能,而不是过程
。
Process
将自动迭代该集合,您不希望在此处重复该集合
您的脚本将如下所示:
$ExampleList | Test-Contains "element"
您可以创建前缀运算符,但不能创建修复中或修复后运算符,例如:
Set-Alias ?: Invoke-Ternary
function Invoke-Ternary {
param(
[Parameter(Mandatory, Position=0)]
[scriptblock]
$Condition,
[Parameter(Mandatory, Position=1)]
[scriptblock]
$TrueBlock,
[Parameter(Mandatory, Position=2)]
[scriptblock]
$FalseBlock,
[Parameter(ValueFromPipeline, ParameterSetName='InputObject')]
[psobject]
$InputObject
)
Process {
if ($pscmdlet.ParameterSetName -eq 'InputObject') {
Foreach-Object $Condition -input $InputObject | Foreach {
if ($_) {
Foreach-Object $TrueBlock -InputObject $InputObject
}
else {
Foreach-Object $FalseBlock -InputObject $InputObject
}
}
}
elseif (&$Condition) {
&$TrueBlock
}
else {
&$FalseBlock
}
}
像这样使用:
$toolPath = ?: {[IntPtr]::Size -eq 4} {"$env:ProgramFiles(x86)\Tools"} {"$env:ProgramFiles\Tools"}}
经过思考,我得出了以下结论: 不确定这是不是比乔恩·蒂尔扬的答案更好
function Op {
Param (
# this operator is the reverse of -contains
[switch] $isIn,
# this operator is just an example
[switch] $Plus
)
if ($isIn) {
if ($args.Length -ne 2) {
throw "Requires two arguments"
}
return ($args[1] -contains $args[0])
}
elseif ($Plus) {
if ($args.Length -ne 2) {
throw "Requires two arguments"
}
return ($args[0] + $args[1])
}
}
用法示例:
PS> $ExampleList = @("alpha", "bravo", "charlie")
PS> Op "alpha" -isIn $ExampleList
True
PS> Op "delta" -isIn $ExampleList
False
PS> Write-Host ("Answer: " + (Op 5 -plus 7))
Answer: 12
我知道比赛已经很晚了。。但我想我会提供一个讨厌的黑客替代品。。唯一的好处是制作“看起来”类似于C#操作符的东西
Set-Alias ?: Invoke-Ternary
Function Invoke-Ternary {
[cmdletbinding()]
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[object]$Condition,
[Parameter(Mandatory=$true, Position=0)]
[Alias('FirstExpression')]
[object]$Consequent,
[Parameter(Mandatory=$true, Position=1)]
[Alias('SecondExpression')]
[object]$Alternative
)
$isTrue = if($Condition.GetType().Name -eq 'Scriptblock'){
Invoke-Command -ScriptBlock $Condition
} else {
$Condition
}
if ($isTrue) {
if($Consequent.GetType().Name -eq 'Scriptblock'){
Invoke-Command -ScriptBlock $Consequent
} else {
$Consequent
}
} else {
if($Alternative.GetType().Name -eq 'Scriptblock'){
Invoke-Command -ScriptBlock $Alternative
} else {
$Alternative
}
}
}
{[IntPtr]::Size -eq 4} |?: 'I like Soup' {'test'|?: 3 ('{0} prefer toast' -f 'We')}
{[IntPtr]::Size -eq 8} |?: 'I like Soup' {$false|?: 3 ('{0} prefer toast' -f 'We')}
虽然这实际上只不过是第一个表达式的字符串被分号分隔(有利于冒号),但它说明了有多种方法可以实现这种行为。
话虽如此。。我希望能为您创建官方运营商
三元和空合并运算符。。当我在做的时候。。正式的Use对象(使用语句(而不是指令))也不错。在此之前,我将继续我的小技巧,但这是一个很好的梦想。这是一个很好的观点,管道使每个cmdlet都成为一个中缀运算符使用编辑器的“Code”函数将整个代码段作为一个代码块,这有助于提高答案的可读性,“我不是简单地在每一行上打勾。@程序员丹,而是对它进行了编辑。它现在在队列中。虽然我喜欢拆分字符串的想法,但使用正则表达式计算表达式很快就会变得混乱。。例如,如果表达式包含字符串格式怎么办?但是,您是对的,我在前面的代码中没有正确地计算条件。查看更新。