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

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.