2

I have a weird PowerShell problem. I am trying to pass into a class method multiple parameters, but it fails. I was able to pass in multiple parameters to a global function instead and that worked. Trying to pass in a variable amount of parameters to a class method instead fails!

Here is my code:

class TestParams {
    [int] $dummyVar

    TestParams() {
        $this.dummyVar = 0
    }

    [void]myMethod() {
        for ($index = 0; $index -lt $args.Count; $index++) {
            Write-Host $args[$index]
        }
    }
}

function testFunc() {
    for ($index = 0; $index -lt $args.Count; $index++) {
        Write-Host $args[$index]
    }
}

testFunc '1' '2' '3' # works

$myTestObj = New-Object TestParams
$myTestObj.myMethod "A" "B" "C" # fails

As you can see from running my code it gives error messages such as:

At C:\*****\testParams.ps1:25 char:21
+ $myTestObj.myMethod "A" "B" "C"
+                     ~~~
Unexpected token '"A"' in expression or statement.

I do not know what is causing this error! Can you guys help me debug this?

2
  • 2
    Method calls use parentheses and commas. Commented Feb 25, 2019 at 23:29
  • 1
    As Mike said, it's $obj.MyMethod('A', 'B', 'C') with methods, and Invoke-Function 'A' 'B' 'C' with (advanced) functions. Commented Feb 25, 2019 at 23:42

2 Answers 2

3

You need to declare the parameters in the method definition:

[void]
myMethod( [array]$arguments ) {
    for ($index = 0; $index -lt $arguments.Count; $index++) {
        Write-Host $arguments[$index]
    }
}

Note that I intentionally changed the automatic variable name args to something else, otherwise it won't work.

In order to call the method, use the following syntax:

$myTestObj.myMethod(@('A', 'B', 'C'))
# or
$argument = 'A', 'B', 'C'
$myTestObj.myMethod($argument)
Sign up to request clarification or add additional context in comments.

2 Comments

is [array] the same as [object[]]? I had a dynamic number of arguments to pass, each of which could contain multiple values, so I ended up using [object[]]. Would [array] have worked equally well here? Sorry not able to test it myself at this time.
@Blaisem either would have worked - all array types inherit from [array], and @() produces an [object[]] - so @() would satisfy either constraint:)
3

PowerShell custom classes (PSv5+) work more like C# code, not like PowerShell functions and scripts:

  • Method / constructor declarations as well as calls must use method syntax, i.e., (...) around a list of ,-separated arguments rather than command syntax (space-separated arguments without enclosing (...)); e.g., if .MyMethod() had 3 distinct parameters:

    • $obj.MyMethod('A', 'B', 'C') instead of $obj.MyMethod 'A' 'B' 'C'
  • Any arguments you pass must bind to formally declared parameters - there is no support for accessing arbitrary arguments via automatic variable$Args.[1]

  • There is no implicit output behavior: Unless methods don't declare a return type or use [void], they must use return to return a value.

Mathias R. Jessen's helpful answer shows how to implement your method with an open-ended number of arguments via an array parameter, emulating the $Args functionality available only to functions.


[1] Due to a bug as of PowerShell Core 6.2.0-rc.1, $Args can unexpectedly be referenced in a method - despite not having been initialized - but always evaluates to an empty array - see this GitHub issue.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.