如何在PowerShell(> 5.0)类中创建只读属性

时间:2017-01-15 16:08:30

标签: powershell

自5.0版以来引入了PowerShell类,我想知道是否可以创建只读属性以及如何创建它。属性值从内部逻辑填充,用户可以读取但不设置它。

考虑以下代码来创建一个类,假设我想将属性“Year”设为只读:

class Car {
    [string] $Maker;
    [string] $Model;
    [string] $Year;
    [int] $Odometer ;


    [void] Drive([int] $NbOfKM) { 
        $this.Odometer += $NbOfKM;  
     }

    Car(){
    }

    Car([int] $Odometer){
        $this.$Odometer = $Odometer;
    }
}

2 个答案:

答案 0 :(得分:7)

不幸的是,PowerShell中没有getter / setter支持。

你可以做的是使用hidden关键字隐藏属性,只提供获取值的方法,但只在内部设置。然后“setter”变得不易被发现。

答案 1 :(得分:2)

我没有足够的声誉评论斯图尔特的回答。但是,这建立在他的答案之上,因为解决方法是覆盖setter方法。

我发现您可以使用ScriptProperty以不雅的方式实现getter和setter。两个相关职位: Powershell class implement get set propertyhttps://powershell.org/forums/topic/class-in-powershell-5-that-run-custom-code-when-you-set-property/。 我更喜欢第二种,因为它将动态代码放入构造函数中。我的代码中的一个例子:

class MyClass {
    MyClass () {
        $this.PSObject.Properties.Add(
            (New-Object PSScriptProperty 'ReadOnlyProperty', {$this._ROF})
        )
    }

    hidden [string]$_ROF = 'Readonly'
}

PSScriptProperty的构造函数采用一个名称,然后是一个或两个脚本块;第一个是getter,第二个(如果提供)是setter。 https://msdn.microsoft.com/en-us/library/system.management.automation.psscriptproperty(v=vs.85).aspx

这种方法的缺点:

  • 您必须手动创建支持字段(我称之为_ROF)
  • 像这样动态定义属性很难看。你不能在类体中声明属性,因为你是动态地添加它(基本上是使用Add-Member)
  • 您最终得到的是ScriptProperty而不是Property
  • 如果您尝试分配给只读属性,则会获得SetWithoutSetterFromScriptProperty异常而不是PropertyAssignmentException。