4

I want to make a call to the parent function from its overidden function, i isolated my problem in the following code:

class SomeClass{
  [type]GetType(){
    write-host 'hooked'
    return $BaseClass.GetType() # how do i call the BaseClass GetType function??
  }
}
SomeClass::new().GetType()

i am expecting an output like this:

hooked
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     SomeClass                                System.Object
1
  • 2
    Object.GetType() is non-virtual and cannot be overridden (although you can hide it in various ways). What exactly are you trying to accomplish? Commented Mar 11, 2022 at 14:42

1 Answer 1

10

In oder to call a method on the base class, cast $this to it (([object] $this).GetType(), in your case, given that your class implicitly derives from [object](System.Object)):

class SomeClass  {
  [type]GetType(){
    Write-Verbose -Verbose hooked!
    # Casting to [object] calls the original .GetType() method.
    return ([object] $this).GetType()
  }
}

[SomeClass]::new().GetType()

As an aside re referring to the base class in PowerShell custom classes:

  • PowerShell only allows you to reference the base class via the abstract base identifier in base-class constructor calls:

    class Foo { [int] $Num; Foo([int] $Num) { $this.Num = $Num } }
    class FooSub : Foo { FooSub() : base(42) { } } # Note the `: base(...)` part
    [FooSub]::new().Num # -> 42
    
  • In methods, the only (non-reflection-based) way to refer to the base class is via a type literal (cast), which in essence requires you to hard-code the base-class name (as also shown with ([object] $this) above):

    class Foo { [string] Method() { return 'hi' } }
    # Note the need to name the base class explicitly, as [Foo].
    class FooSub : Foo { [string] Method() { return ([Foo] $this).Method() + '!' } }
    [FooSub]::new().Method() # -> 'hi!'
    
    • Caveat: There appears to be a bug in Windows PowerShell (no longer present in PowerShell (Core) 7+), where calling a base class' method fails if the base class is a generic type that is constructed with type argument [pscustomobject] aka [psobject]. Use a reflection-based workaround in that case; e.g.:

      class Foo : System.Collections.ObjectModel.Collection[pscustomobject] {
        [void] Add([pscustomobject] $item) {
          Write-Verbose -Verbose hooked!
          # Use reflection to call the base class' .Add() method.
          # Note: In *PowerShell Core*, this workaround isn't necessary, and the usual would work:
          #         ([System.Collections.ObjectModel.Collection[pscustomobject]] $this).Add($item)
          # Note the use of .GetMethod() and .Invoke()
          [System.Collections.ObjectModel.Collection[pscustomobject]].GetMethod('Add').Invoke($this, [object[]] $item)
        }
      }
      
Sign up to request clarification or add additional context in comments.

1 Comment

Would it be worthwhile to add in the GetMethod of the base type from your answer here?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.