With the introduction of PowerShell class since version 5.0, I was wondering if it is possible to create a read-only property and how to do it. The property value is populated from the internal logic and the user can read it but not set it.
Consider the following code to create a class and let's say I want to make the property "Year" as read-only :
class Car {
[string] $Maker;
[string] $Model;
[string] $Year;
[int] $Odometer ;
[void] Drive([int] $NbOfKM) {
$this.Odometer += $NbOfKM;
}
Car(){
}
Car([int] $Odometer){
$this.$Odometer = $Odometer;
}
}
Although Powershell doesn't have real readonly class properties, we can mimic them in two elegant ways: Class methods as getter and setter functions. Script properties with getter and setter functions.
Object properties To get the properties of an object, use the Get-Member cmdlet. For example, to get the properties of a FileInfo object, use the Get-ChildItem cmdlet to get the FileInfo object that represents a file. Then, use a pipeline operator ( | ) to send the FileInfo object to Get-Member .
Unfortunately there is no getter/setter support in PowerShell.
What you can do though is use the hidden keyword to hide the property and only provide a method to get the value, but only set it internally. Then the "setter" becomes less discoverable.
I don't have enough reputation to comment on Stuart's answer. However, this builds on his answer, because the workaround is to override the setter method.
I've found that you can implement getters and setters in an inelegant way by using ScriptProperty. Two relevant posts: Powershell class implement get set property, https://powershell.org/forums/topic/class-in-powershell-5-that-run-custom-code-when-you-set-property/. I prefer the second, because it puts the dynamic code into the constructor. An example from my code:
class MyClass {
MyClass () {
$this.PSObject.Properties.Add(
(New-Object PSScriptProperty 'ReadOnlyProperty', {$this._ROF})
)
}
hidden [string]$_ROF = 'Readonly'
}
The constructor for PSScriptProperty takes a name and then one or two scriptblocks; the first is the getter, the second (if provided) is the setter. https://msdn.microsoft.com/en-us/library/system.management.automation.psscriptproperty(v=vs.85).aspx
Downsides of this approach:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With