Powershell 覆盖赋值和比较运算符
Powershell Overriding Assignment and Comparison operators
使用 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 中执行此操作。不幸的是,经过几次 google 搜索并在 Stack Overflow 上搜索后,我几乎要放弃了。但后来我发现 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
使用 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 中执行此操作。不幸的是,经过几次 google 搜索并在 Stack Overflow 上搜索后,我几乎要放弃了。但后来我发现 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