powershell - PowerShell IComparable 与子类
问题描述
假设我们有这 3 个类:
Class BaseClass : System.IComparable
{
[int] $Value
BaseClass([int] $v)
{
$this.Value = $v
}
[int] CompareTo($that)
{
If (-Not($that -is [BaseClass])) {
Throw "Not comparable!!"
}
return $this.Value - $that.Value
}
}
Class SubClassA : BaseClass
{
SubClassA([int] $v) : base($v)
{
}
}
Class SubClassB : BaseClass
{
SubClassB([int] $v) : base($v)
{
}
}
当我们比较以下实例时,此实现效果很好BaseClass
:
$base1 = [BaseClass]::new(1)
$base2 = [BaseClass]::new(2)
Write-Output ($base1 -lt $base2)
# Output: True
Write-Output ($base1 -gt $base2)
# Output: False
但是我找不到比较两个子类的两个实例的方法:
$subA1 = [SubClassA]::new(1)
$subB2 = [SubClassB]::new(2)
Write-Output (([BaseClass]$subA1) -lt ([BaseClass]$subB2))
PowerShell 无法执行此代码,引发此错误:
Impossibile confrontare "SubClassA" con "SubClassB".
Errore:
"Impossibile convertire il valore "SubClassB" di tipo "SubClassB" nel tipo "SubClassA"."
从意大利语翻译成英语,这个错误信息听起来像:
Unable to compare "SubClassA" with "SubClassB".
Error:
"Unable to convert the value "SubClassB" of type "SubClassB" to the type "SubClassA"."
为什么会出现这个错误?我们如何将 的实例SubClassA
与 的实例进行比较,SubClassB
就好像它们是 的两个实例一样BaseClass
?
PS:输出$PSVersionTable
:
PSVersion 5.1.17134.1
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17134.1
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
解决方案
这种行为确实令人惊讶,我看到您已经打开了一个 GitHub 问题来讨论它。
一些额外的想法:
PowerShell 的运算符通常具有扩展的语义,通常不应假定在所有情况下都与 C# 对应的运算符相同 - 但是,在这种特殊情况下,它们显然应该(见下文)。
-lt
实际上与基类实例一起工作的事实已经指出了一个区别:等效的 C# 类还需要显式重载<
and>
运算符,以支持使用<
.接口实现由 PowerShell 和 C# 中的派生类继承,因此无需强制转换为基类即可应用
-lt
.
这里似乎发生的是,PowerShell 盲目地尝试将 RHS 转换为 LHS 的类型,而不考虑它们的共享基类。
如果 RHS 类型直接派生自 LHS 类型,则不会出现问题(反之亦然);例如:
$base1 -lt $subA1 # OK: SubClassA (RHS) derives from BaseClass (LHS)
$subA1 -lt $base1 # !! BREAKS: BaseClass (RHS) does NOT derive from SubClassA (LHS)
推荐阅读
- android - ds.child(key).setValue() 进入子级时出错
- avr - AVR 和 FATFS 多块读取
- python - VB,净值。您如何处理要求多个用户输入的 cmd 进程
- magento2 - Magento 2 UI dataprovider 不加载数据
- python - 字典到面向对象的转换
- reactjs - React Redux -> 为什么我得到 TypeError: state.item is not iterable
- python-3.x - 如何使用 TensorFlow 训练两塔模型?
- algorithm - NIce Subsequence - 最长递增子序列的变体
- redux - 登录后不导航到经过身份验证的页面
- r - 通过列选择将数据帧拆分为多个数据帧