在 PowerShell 5 或更高版本中创建自定义类时,可以重载比较运算符(通过从类派生[System.IComparable]并创建方法CompareTo())和四个“算术”运算符+、-、*和/(通过创建静态方法op_Addition、op_Subtraction、op_Multiply和op_Division)。
重载模运算符所需的静态方法是什么%?或者这根本不可能?
mkl*_*nt0 10
为了补充最伟大的本德的有用答案:
\n下面是C#/PowerShell 运算符符号/名称到其op_*元数据方法名称的完整映射,这些方法名称必须用于在自定义 PowerShell 类 (v5+) 中实现运算符重载;摘自运算符重载框架设计指南的
笔记:
\n该列表仅限于您可以在 PowerShell 中重载的那些运算符,即使其中只有一个子集在实践中可能有意义。
\n运算符-eqand-ne以及-lt/-le和-gt/-ge必须使用不同的方法重载 - 见下文。
+ op_Addition \n- op_Subtraction\n* op_Multiply\n/ op_Division\n% op_Modulus\n-bxor op_ExclusiveOr\n-band op_BitwiseAnd\n-bor op_BitwiseOr\n-shl op_LeftShift\n-shr op_RightShift\n-bnot op_OnesComplement\nRun Code Online (Sandbox Code Playgroud)\n重要的:
\n\n\nX 避免定义运算符重载,除非是感觉像原始(内置)类型的类型。
\n
\n \xe2\x9c\x93 考虑在应该感觉像原始类型的类型中定义运算符重载。
在 PowerShell 中:
\n-lt, -le,-gt -ge必须通过实现接口来间接重载System.IComparable。
同样,-eqand-ne必须通过重写继承的Object.Equals()andObject.GetHashCode()方法来重载。
二元和运算符也适用于一元调用; 例如,被隐式地视为。+-+$var0 + $var
复合赋值,例如+=隐式使用重载运算符。
++并且--不能重载 - 它们被硬编码为仅对数字类型进行操作。
此示例定义了一个自定义[Fruit]类:
+通过静态方法重载op_Addition(),因此您可以“添加”两个实例。
通过重写实例方法和关联方法来重载-eq/ 。-neObject.Equals()Object.GetHashCode()
通过其实现接口来重载-lt/-le和-gt/-geSystem.IComparableCompareTo()。
class Fruit : System.IComparable\n{\n [string] $Kind\n Fruit([string] $Kind) { $this.Kind = $kind }\n\n # Operator overloading: Custom-define +\n # Note: must be static, return type must be the type at hand, \n # and the operands must both be of the type at hand.\n static [Fruit] op_Addition([Fruit] $a, [Fruit] $b) { return [Fruit]::new((\'Cross-breed of {0} and {1}\' -f $a.Kind, $b.Kind)) }\n \n # Custom-define -lt / -le and -gt / -ge, via the System.IComparable interface.\n [int] CompareTo([object] $other) {\n # Simply perform (case-insensitive) lexical comparison on the .Kind\n # property values.\n if ($this.Kind -eq $other.Kind) {return 0 }\n if ($this.Kind -lt $other.Kind) {return -1 }\n return 1 # -gt\n }\n\n # Custom-define -eq / -ne, by overriding Object.Equals()\n # Note that this also requires overriding Object.GetHashCode(),\n # because any two instances that compare the same must report the same\n # hash code.\n [bool] Equals([object] $other) {\n # Two [Fruit] instance, though distinct reference-type instances,\n # should be considered equal if their .Kind property is equal, case-insensitively.\n return $this.Kind -eq $other.Kind\n }\n # Since [Fruit] instances are compared by their .Kind property value (a [string]),\n # we defer to the latter\'s .GetHashCode() value, which seemingly is invariant \n # for a given string. However, we normalize to *lowercase* first, given that \n # PowerShell\'s string comparisons are case-insensitive by default.\n [int] GetHashCode() {\n return $this.Kind.ToLowerInvariant().GetHashCode()\n }\n\n}\nRun Code Online (Sandbox Code Playgroud)\n您现在可以“添加”到[Fruit]实例:
PS> [Fruit]::new(\'orange\') + [Fruit]::new(\'kiwi\')\n\nKind\n----\nCross-breed of orange and kiwi\nRun Code Online (Sandbox Code Playgroud)\n也就是说,[Fruit]返回了一个新实例,其.Kind属性反映了“添加”在一起的水果。
# Two [Fruit] instances are considered equal if their .Kind property values\n# are case-sensitively equal.\nPS> [Fruit]::new(\'orange\') -eq [Fruit]::new(\'Orange\')\nTrue\nRun Code Online (Sandbox Code Playgroud)\n# Two [Fruit] instances are considered less / greater than based on \n# lexical comparison (\'a\' before \'b\', ...), case-insensitively.\nPS> [Fruit]::new(\'apple\') -lt [Fruit]::new(\'orange\')\nTrue\nRun Code Online (Sandbox Code Playgroud)\n要测试比较重载(-lt/-le和-gt/ -ge),请查看该类型的实例是否实现System.IComparable:
[Fruit]::new(\'apple\') -is [IComparable]对于重载/没有简单的测试,因为根据定义,所有对象上都存在实现和方法。但是,如果手头的类型是引用类型(所有 PowerShell 自定义类都是引用类型),您可以从两个不同的实例进行比较来推断它们相等且已重载;例如,屈服意味着-eq-neEquals()Get-HashCode()-eq-ne[Fruit]::new(\'orange\') -eq [Fruit]::new(\'orange\')$true-eq超载。
要测试基于静态op_*方法的运算符重载:
Get-Member -Static来:PS> [Fruit]::new(\'orange\') | Get-Member -Static -Name op_*\n\n TypeName: Fruit\n\nName MemberType Definition\n---- ---------- ----------\nop_Addition Method static Fruit op_Addition(Fruit a, Fruit b)\n\nRun Code Online (Sandbox Code Playgroud)\nGet-Member -Static -Force(-Force在这种情况下是必需的):# Same output as above.\n[Fruit] | Get-Member -Static -Force -Name op_*\nRun Code Online (Sandbox Code Playgroud)\n请注意,只有真正重载的运算符才会以这种方式出现。\n诸如此类的原始 .NET 类型[int]没有此类方法。
| 归档时间: |
|
| 查看次数: |
1129 次 |
| 最近记录: |