codewario
codewario

Reputation: 21448

Set static property on static class in PowerShell

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

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

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?

No

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

Related Questions