【问题标题】:Powershell Overriding Assignment and Comparison operatorsPowershell 覆盖赋值和比较运算符
【发布时间】:2019-07-16 19:07:27
【问题描述】:

使用 Powershell 5,您现在可以实现自定义类。最终,您会想要开始重载运算符以执行诸如

之类的操作
class Number
{
    [int] $value = 0

    Number() {} # empty constructor

    Number ([int]$somethingElse)
        {$this.value = $somethingElse}
}

$one = [number]::new(1)
$two = [number]::new(2)
$three = $one + $two
if ($three -eq ($one + $two))
    {"3 = 1 + 2"}
else
    {"3 <> 1 + 2 "}

但这似乎没有很好的记录,在 Stack Overflow 上搜索后我找不到如何做到这一点

【问题讨论】:

    标签: powershell class operator-overloading powershell-5.0


    【解决方案1】:

    通常认为您不能在 powershell 中执行此操作。不幸的是,经过几次谷歌搜索和 Stack Overflow 上的搜索,我几乎要放弃了。但后来我在 gist 上发现了this post,结果证明你可以!

    考虑到我很难发现,我想为其他人(以及当我很快忘记如何做这件事时的未来自己)提供一个清晰且格式正确的示例

    感谢 JFFail 将 this 发布到 Github

    您将需要酌情重载这些内容,它们应该是不言自明的,但如果有什么问题,请随时询问

    SetValue([int]$newValue)
    GetValue()
    [boolean] Equals($otherNumber)
    [string] ToString() # you can get more advanced by overloading "IConvertible.ToType" but that's a whole can of worms all it's own
    static [MyClass] op_Addition   ([MyClass]$first, [MyClass]$second)
    static [MyClass] op_Subtraction([MyClass]$first, [MyClass]$second)
    static [MyClass] op_Multiply   ([MyClass]$first, [MyClass]$second)
    static [MyClass] op_Division   ([MyClass]$first, [MyClass]$second)
    

    对于-gt 和-lt,您需要使用以下内容。请注意,虽然这确实支持-eq,但您可以使用Equals(object) 自行获得它,如上所示,并且不需要从IComparable 继承

    class MyClass : System.IComparable 
    # requires inheritance from System.IComparable
    
    [int] CompareTo($otherNumber)
    # CANNOT declare type in parameter declaration, you'd have to check it later.
    # 1 is greater than
    # 0 is equal
    # -1 is less than
    # $null can be returned to indicate invalid comparison
    

    这是一个工作示例

    # If you don't need -lt or -gt then you don't have to inherit from System.IComparable
    class Number : System.IComparable
    {
        [int] $value = 0
    
        Number() {} # empty constructor
    
        Number ([int]$somethingElse)
            {$this.value = $somethingElse}
    
        [void] SetValue ([int]$newValue)
            {$this.value = $newValue}
    
        [int] GetValue()
            {return $this.value}
    
        [boolean] Equals($otherNumber)
        {
            if ($this.value -eq $otherNumber.GetValue())
                {return $true}
            else
                {return $false}
        }
    
        [int] CompareTo($otherNumber)
        {
            if ($this.value -gt $otherNumber.GetValue()) {return 1}
            if ($this.value -eq $otherNumber.GetValue()) {return 0}
            if ($this.value -lt $otherNumber.GetValue()) {return -1}
            return $null
        }
    
        [string] ToString()
            {return $this.value.ToString()}
    
        static [Number] op_Addition ([Number]$first, [Number]$second)
            {return [Number]::new($first.GetValue() + $second.GetValue())}
    
        static [Number] op_Subtraction([Number]$first, [Number]$second)
            {return [Number]::new($first.GetValue() - $second.GetValue())}
    
        static [Number] op_Multiply([Number]$first, [Number]$second)
            {return [Number]::new($first.GetValue() * $second.GetValue())}
    
        static [Number] op_Division([Number]$first, [Number]$second)
            {return [Number]::new($first.GetValue() / $second.GetValue())}
    }
    
    # Very Basic Unit Tests
    $firstNumber = [Number]::new(8)
    $secondNumber = [Number]::new(12)
    $thirdNumber = [Number]::new(8)
    
    if ($firstNumber -eq $secondNumber)
        {Write-Output ("{0} == {1}" -F $firstNumber, $secondNumber)}
    else
        {Write-Output ("{0} <> {1}" -F $firstNumber, $secondNumber)}
    
    if ($firstNumber -eq $thirdNumber)
        {Write-Output ("{0} == {1}" -F $firstNumber, $thirdNumber)}
    else
        {Write-Output ("{0} <> {1}" -F $firstNumber, $thirdNumber)}
    
    switch ($true)
    {
        ($firstNumber -gt $secondNumber) {Write-Output ("{0} > {1}" -F $firstNumber, $secondNumber)}
        ($firstNumber -eq $secondNumber) {Write-Output ("{0} == {1}" -F $firstNumber, $secondNumber)}
        ($firstNumber -lt $secondNumber) {Write-Output ("{0} < {1}" -F $firstNumber, $secondNumber)}
    }
    
    $fourthNumber = $firstNumber + $secondNumber
    Write-Output ("{0} = {1} + {2}" -F $fourthNumber, $firstNumber, $secondNumber)
    
    $fifthNumber = $secondNumber - $thirdNumber
    Write-Output ("{0} = {1} - {2}" -F $fifthNumber, $secondNumber, $thirdNumber)
    
    $sixthNumber = $firstNumber * $secondNumber
    Write-Output ("{0} = {1} * {2}" -F $sixthNumber, $firstNumber, $secondNumber)
    
    $seventhNumber = $sixthNumber / $firstNumber
    Write-Output ("{0} = {1} / {2}" -F $seventhNumber, $sixthNumber, $firstNumber)
    

    这是输出

    > 8 <> 12
    > 8 == 8
    > 8 < 12
    > 20 = 8 + 12
    > 4 = 12 - 8
    > 96 = 8 * 12
    > 12 = 96 / 8
    

    【讨论】:

      猜你喜欢
      • 2010-10-13
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 2021-06-16
      • 2014-10-16
      • 2016-12-23
      • 2011-08-03
      • 2011-11-16
      相关资源
      最近更新 更多