powershell

Calling a method returned from another method in Powershell


I'm trying to invoke a function returned from another function. Basically I have a bunch of functions to be called depending on some condition:

function func1 {write-host "hello func1"}
function func2 {write-host "hello func2"}
# ...

function getfunc([char]$condition) {
    switch ($condition) {
        '1' {return func1}
        '2' {return func2}
        # ...
    }
}

function main {
    &getfunc('1')
}

Calling main yields the correct result hello func1. However, I can't seem to make these work for class methods as they require me to specify the type of returned value for a method:

class MyClass {

    [char]$condition

    [void] func1() {write-host "hello func1"}
    [void] func2() {write-host "hello func2"}
    # ...

    [string[]] getfunc() {        # what type to put in here ?
        switch ($this.condition) {
            '1' {return $this.func1}
            '2' {return $this.func2}
            # ...
        }
        return ""
    }

    [void] main() {
        $this.condition = '1'
        & $this.getfunc()
    }
}

[MyClass]::new().main()

I tried using [string[]] with no luck:

& : The term 'void func1()' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

How do I do this ?


Solution

  • Dereferencing a class method like in your example yields an object of type System.Management.Automation.PSMethod - you can invoke it via the Invoke() method, but not &, so do:

    class MyClass {
        [int] $Condition
        [void] func1() { Write-host "hello func1" }
        [void] func2() { Write-host "hello func2" }
    
        [System.Management.Automation.PSMethod] GetFunc() {
            $func = switch ($this.Condition) {
                1 { $this.func1 }
                2 { $this.func2 }
            }
            return $func
        }
    
        static [void] Main([int]$condition) {
            # create instance
            $inst = [MyClass]@{ Condition = $condition }
    
            # select function
            $func = $inst.GetFunc()
    
            # invoke selected function
            $func.Invoke()
        }
    }
    
    [MyClass]::Main(1)