Powershell类实现get set属性

时间:2016-09-27 06:12:12

标签: class powershell properties

如何使用Powershell类实现get / set属性。 请看下面我的例子:

Class TestObject
{
  [DateTime]$StartTimestamp = (Get-Date)
  [DateTime]$EndTimestamp = (Get-Date).AddHours(2)

  [TimeSpan] $TotalDuration {
    get {
      return ($this.EndTimestamp - $this.StartTimestamp)
    }
  }

  hidden [string] $_name = 'Andreas'
  [string] $Name {
    get {
      return $this._name
    }
    set {
      $this._name = $value
    }
  }
}

New-Object TestObject

2 个答案:

答案 0 :(得分:6)

您可以使用Add-Member ScriptProperty来实现一种getter和setter:

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

新建它会调用$_p的初始化程序,它会添加scriptproperty p

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

使用属性p会产生以下结果:

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

这种技术存在一些缺陷,这些缺陷主要与Add-Member行的冗长和容易出错有关。为了避免这些陷阱,我实施了Accessor,您可以找到here

使用Accessor代替Add-Member会进行大量的错误检查,并将原始类的实现简化为:

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

答案 1 :(得分:1)

这就是我要做的事

  [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)"
    }
  });