如何创建自定义Powershell操作符?

如何创建自定义Powershell操作符?,powershell,customization,Powershell,Customization,是否可以在Powershell中创建自定义运算符?我该怎么做呢?我搜索过谷歌,但什么都没找到 我指的是中缀操作符: $ExampleList-包含“元素” 我已经创建了cmdlet(使用Powershell和C#)、模块等,所以我只需要大致的笔划。您可以创建一个cmdlet并将列表导入其中。 要评估列表,请确保使用结束功能,而不是过程。 Process将自动迭代该集合,您不希望在此处重复该集合 您的脚本将如下所示: $ExampleList | Test-Contains "element"

是否可以在Powershell中创建自定义运算符?我该怎么做呢?我搜索过谷歌,但什么都没找到

我指的是中缀操作符:

$ExampleList-包含“元素”


我已经创建了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”函数将整个代码段作为一个代码块,这有助于提高答案的可读性,“我不是简单地在每一行上打勾。@程序员丹,而是对它进行了编辑。它现在在队列中。虽然我喜欢拆分字符串的想法,但使用正则表达式计算表达式很快就会变得混乱。。例如,如果表达式包含字符串格式怎么办?但是,您是对的,我在前面的代码中没有正确地计算条件。查看更新。