Powershell class implement get set property Powershell class implement get set property powershell powershell

Powershell class implement get set property


You can use Add-Member ScriptProperty to achieve a kind of getter and setter:

class c {    hidden $_p = $($this | Add-Member ScriptProperty 'p' `        {            # get            "getter $($this._p)"        }`        {            # set            param ( $arg )            $this._p = "setter $arg"        }    )}

Newing it up invokes the initializer for $_p which adds scriptproperty p:

PS C:\> $c = [c]::new()

And using property p yields the following:

PS C:\>$c.p = 'arg value'PS C:\>$c.pgetter setter arg value

This technique has some pitfalls which are mostly related to how verbose and error-prone the Add-Member line is. To avoid those pitfalls, I implemented Accessor which you can find here.

Using Accessor instead of Add-Member does an amount of error-checking and simplifies the original class implementation to this:

class c {    hidden $_p = $(Accessor $this {        get {            "getter $($this._p)"        }        set {            param ( $arg )            $this._p = "setter $arg"        }    })}


Here's how I went about it

  [string]$BaseCodeSignUrl;   # Getter defined in __class_init__.  Declaration allows intellisense to pick up property  [string]$PostJobUrl;        # Getter defined in __class_init__.  Declaration allows intellisense to pick up property  [hashtable]$Headers;        # Getter defined in __class_init__.  Declaration allows intellisense to pick up property  [string]$ReqJobProgressUrl; # Getter defined in __class_init__.  Declaration allows intellisense to pick up property  # Powershell lacks a way to add get/set properties.  This is a workaround  hidden $__class_init__ = $(Invoke-Command -InputObject $this -NoNewScope -ScriptBlock {    $this | Add-Member -MemberType ScriptProperty -Name 'BaseCodeSignUrl' -Force -Value {      if ($this.Production) { [CodeSign]::CodeSignAPIUrl } else { [CodeSign]::CodeSignTestAPIUrl }    }    $this | Add-Member -MemberType ScriptProperty -Name 'PostJobUrl' -Force -Value {      "$($this.BaseCodeSignUrl)/Post?v=$([CodeSign]::ServiceApiVersion)"    }    $this | Add-Member -MemberType ScriptProperty -Name 'Headers' -Force -Value {      @{        _ExpireInMinutes=[CodeSign]::Timeout.Minutes;        _CodeSigningKey=$this.Key;        _JobId=$this.JobId;        _Debug=$this.Dbg;        _Token=$this.Token;      }    }    $this | Add-Member -MemberType ScriptProperty -Name 'ReqJobProgressUrl' -Force -Value {      "$($this.BaseCodeSignUrl)Get?jobId=$($this.JobId)"    }  });