Powershell类继承行为

Powershell类继承行为,powershell,class,inheritance,Powershell,Class,Inheritance,我正试图利用PowerShell的继承来创建一个从现有类继承的类,但没有看到基于该类的预期行为 下面是一个突出问题的简单示例: class child : System.Xml.XmlDocument { [String] ToString(){ return 'ChildString' } [void] LoadXml([string]$content) { Write-Host 'LoadXml' ([System.X

我正试图利用PowerShell的继承来创建一个从现有类继承的类,但没有看到基于该类的预期行为

下面是一个突出问题的简单示例:

class child : System.Xml.XmlDocument {
    [String] ToString(){
        return 'ChildString'
    }

    [void] LoadXml([string]$content) {
        Write-Host 'LoadXml'
        ([System.Xml.XmlDocument]$this).LoadXml($content)
    }
}
如果我跑

Write-Host 'XMLDocument Object'
$xml=New-Object xml
$xml.ToString()

Write-Host 'Inherited Object'
$child=New-Object child
$child.ToString()
控制台输出为

XMLDocument Object
#document
Inherited Object
#document
指示未使用子类的
ToString()
方法

另一方面,如果调用
$child.LoadXml('Hello')
,则得到无限递归,这意味着对父对象的调用在该方法中失败

根据我所能找到的,我不希望这些方法会以这种方式运行,我希望有人能帮助我理解我所缺少的东西。我通常更习惯Python;然而,出于安全原因,我不能用另一种编程语言实现这段代码(我不能在要运行的计算机上安装软件)

谢谢


以下是
$PSversionTable.PSVersion
的结果,以供参考:

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      15063  909    

在这两种情况下,对
ToString()
的调用都会被附加到其共同祖先
System.Xml.XmlNode
的其他类型数据覆盖:

PS C:\> Get-TypeData -TypeName System.Xml.XmlNode

TypeName           Members                                                            
--------           -------                                                            
System.Xml.XmlNode {[ToString, System.Management.Automation.Runspaces.CodeMethodData]}
您可以使用
Remove TypeData
在运行时删除它:

Remove-TypeData -TypeName System.Xml.XmlNode
您现在应该看到您的
子对象调用自己的方法,以及从
系统继承的
对象调用
XmlDocument
对象调用
ToString()

XMLDocument Object
System.Xml.XmlDocument
Inherited Object
ChildString
解释并解决隐藏的
.ToString()
方法的问题
尽管该行为可能是模糊的,但它似乎是经过设计的:PowerShell允许自定义.NET类型,即使在派生类中也优先于此类自定义

相比之下,无法从
.LoadXml()
方法调用基类方法闻起来像是一个bug,
,[至少在PowerShell Core v6.1.0中已修复],听起来像

这里有一个解决方案,非常感谢地改编自:


这真的很有趣,解决了我99%的问题。我肯定得多研究一下TypeData。谢谢@谢谢!虽然令人恼火,但我相信这个成员决议顺序对ETS的行为至关重要。我在原始问题中看到的唯一错误是
LoadXml
这件事。我发布了一个关于
LoadXml
调用自身而不是基类的问题:出于我的目的,我可以利用LoadXml函数四处走动,当我测试它时,它的行为方式非常令人惊讶。再加上其他的行为,我觉得我快要疯了。无论如何,我测试了这个变通方法,它确实解决了问题。我希望我能把两个答案都标为已接受。谢谢
class child : System.Xml.XmlDocument {
  [void] LoadXml([string]$content) {
    Write-Host 'LoadXml'
    # Get a function pointer to the base class method...
    $funcPtr = [System.Xml.XmlDocument].GetMethod('LoadXml', [string]).MethodHandle.GetFunctionPointer() 
    # ...and invoke it with this instance.
    [Activator]::CreateInstance([Action[string]], $this, $funcPtr).Invoke($content)
  }
}