Reputation: 21448
I have a class where there are properties on the class, but I only want to be able to set their values internally, but allow a public get accessor on it. Since there is no PS equivalent in classes like this in C#:
public string PropertyName {
get;
private set;
}
I've looked at implementing the following workaround on my class so the "private" members remain hidden with a public accessor for the property:
class MyClass {
hidden [string]$_PropertyName
MyClass( $propertyValue ) {
$this._PropertyName = $PropertyValue
$this | Add-Member -ScriptProperty -Name 'PropertyName' -Value {
return $this.$_PropertyName
} -SecondValue {
throw "Cannot write value to a readonly property"
}
}
}
This works well and does what I want, but this class also has a couple of static properties I want to do the same thing for from its static constructor. While the code above does work for setting the property on the class type itself (substituting [MyClass]
for $this
), there is a small quirk that makes the syntax for accessing the "readonly" property inconsistent with normally accessing static members:
hidden static [string]$_StaticProperty = 'someValue'
static MyClass() {
[MyClass] | Add-Member -ScriptProperty StaticProperty -Value {
return [MyClass]::$_StaticProperty
}
}
I can access StaticProperty
but only as if it were an instance member:
[MyClass]::StaticProperty # ==> $null
[MyClass].StaticProperty # ==> someValue
Is there a way to add a static member to a type using Add-Member
so I can keep the accessor syntax consistent?
Upvotes: 5
Views: 2436
Reputation: 174660
Is there a way to add a static member to a type using Add-Member so I can keep the accessor syntax consistent?
Add-Member
was designed to allow user to add synthetic ETS properties to instance objects - at a time long before anyone was thinking about adding the class
keyword to the language grammar.
Put another way, "static members" carry zero meaning in the context of ETS, because ETS members are tied to the identity of already-instantiated objects.
If you want class member behavior as found in C#, use C#:
Add-Type @'
public class MyClass
{
static MyClass()
{
MyClass.StaticProperty = "some value";
}
public static string StaticProperty { get; private set; }
}
'@
# Use [MyClass]::StaticProperty
Upvotes: 4