powershellclassconstructoroverloading

Is the "new" method name reserved?


Coming from this helpful question/answer: Constructor chaining in PowerShell - call other constructors in the same class.
To be consistent with the way you call a constructor (e.g. [car]::new()) and because "the hidden keyword" doesn't completely hide the method anyways, I am considering to use the method name new() (rather than init() for this constructor "helper" method in my classes. e.g.:

hidden new([string]$make) { $this.new($make, $null) }

It appears to work fine but somehow I fear that there might be a catch by doing so.

Is there any reason I should avoid the name "new" for a PowerShell class method?


Solution

  • Is there any reason I should avoid the name new for a PowerShell Class method?

    From a strictly technical consideration and leaving aside personal preference / opinion, as long as the method is an instance method, then using new as its name shouldn't be a problem.

    As noted in comments, there would be a problem if the method was a static one as you would be conflicting with the new intrinsic member.

    The first problem would be the need to use reflection to invoke your method in the .ctor:

    class Test {
        [string] $MyParam
    
        Test() {
            [Test].GetMethod('new').Invoke($null, $this)
        }
    
        Test([string] $myParam) {
            $this.MyParam = $myParam
        }
    
        hidden static new([Test] $instance) {
            $instance.MyParam = 'default value'
        }
    }
    
    [Test]::new()
    
    # MyParam
    # -------
    # default value
    
    [Test]::new('other value')
    
    # MyParam
    # -------
    # other value
    

    The second problem would be that the overload definitions would be all messed up as they would be showing your method overloads instead of the actual constructor overloads:

    [Test]::new
    
    # OverloadDefinitions
    # -------------------
    # public static void new(Test instance);
    

    The expected here would be (same definitions as if you were doing [Test].GetConstructors()):

    [Test]::new
    
    # OverloadDefinitions
    # -------------------
    # public Test();
    # public Test(string myParam);