Search code examples
powershellclassconstructoroptional-parameters

PowerShell Classes: Is it possible to make a constructors parameter optional?


I am trying to build a "type", for the Timecode convention used in Film/Animation.

I want to accommodate use cases where a user may want to initialise the object with a Timecode string gotten from elsewhere:

$MyTimeCode = [TimeCode]::new("08:06:04.10", 12)

and in other cases, directly with parameters belonging to the classes constructor:

$MyTimeCode = [TimeCode]::new(, 8, 6, 4, 10, 12)

#If I had constructor such as the foloowing in my class definition:
#TimeCode([String]$TimeStamp, [Int]$Hours, [Int]$Minutes, [Int]$Seconds, [Int]$Frames, [Int]$FrameRate)
`

The following Class as an example:

class HelloWorld {
    [String]$Hello
    [String]$World

    HelloWorld([String]$Hello, [String]$World) {
        $This.Hello = $Hello
        $This.World = $World
        }
    }

Attempting to initialise it [HelloWorld]::new("Hello", "World") works fine but with [HelloWorld]::new("Hello") I get an error:

MethodException: Cannot find an overload for "new" and the argument count: "1".

I have been watching some lectures here and there but they are not structured at all and they quickly advance.

The official docs are usually my go to but the "About_Classes" page quickly advances to "inheriting" and "subclasses" etc with the "Rack" and "Devices" examples and its not clear to me how one begins to work with just a single class.

My goal is to familiarise myself with classes and what they can do. The Timecode is secondary.


Solution

  • A constructor that takes a single argument is needed. There can be as many constructors as needed as long as the signature of the parameters is unique for each. This code also creates a default constructor. The members of the default constructor will contain $null when instantiated.

    class HelloWorld {
        [String]$Hello
        [String]$World
    
        HelloWorld([String]$Hello, [String]$World) {
            $This.Hello = $Hello
            $This.World = $World
        }
        HelloWorld([String]$Hello) {
            $This.Hello = $Hello
            $This.World = 'default'
        }
        HelloWorld() {}     # default constructor
    }
    
    $x1 = [HelloWorld]::new('hello', 'world')
    $x1
    $x2 = [HelloWorld]::new('hello')
    $x2
    $x3 = [HelloWorld]::new()
    $x3