Search code examples
powershellclassmethodspropertiespowershell-5.0

Why do powershell class properties require this within their methods?


PSVersion: 5.1.17134.858

I haven't done a whole lot of work with Powershell's classes but here's a simple example of what I'm running into:

class xNode{
   [uint64]$MyID=0
   static [uint64]$ClassID=0

   xNode(){
      $MyID = [xNode]::ClassID++
   }

   [String] ToString(){return "xNode: $MyID"}
}

doesn't parse it gives the two errors:
line 6 $MyID..., "Cannot assign property, use '$this.MyID'."
line 9 ..$MyID", "Variable is not assigned in the method."

I'm trying to use the classes property named $MyID, and this usage appears to be in line with the example given in the help documentation get-help about_Classes, and when I copied their whole example at the end out to a file then tried to run it I was getting the same errors as well for $Head, $Body, $Title,... Of course I can force it to work by adding this.

class xNode{
   [uint64]$MyID=0
   static [uint64]$ClassID=0

   xNode(){
      $this.MyID = [xNode]::ClassID++
   }

   [String] ToString(){return "xNode: $($this.MyID)"}
}

However I'd rather not have to keep typing this. all over the place, is there maybe some environment setting or something I've overlooked?

(Note: to get it to work at the commandline, I also needed to remove all of the blank lines)


Solution

  • However I'd rather not have to keep typing this. all over the place, is there maybe some environment setting or something I've overlooked?

    No, it's working as advertised, you can't reference instance properties inside the class without the $this variable reference.

    Why do powershell class properties require this within their methods?

    (The following is what I'd call "qualified speculation", ie. not an officially sourced explanation)

    PowerShell classes are a bit tricky from an implementers point of view, because a .NET property behaves differently than, say, a parameter in a powershell scriptblock or a regular variable.

    This means that when the language engine parses, analyzes and compiles the code that makes up your PowerShell Class, extra care has to be taken as to which rules and constraints apply to either.

    By requiring all "instance-plumbing" to be routed through $this, this problem of observing one set of rules for class members vs everything else becomes much smaller in scope, and existing editor tools can continue to (sort of) work with very little change.

    From a user perspective, requiring $this also helps prevent accidental mishaps, like overwriting instance members when creating new local variables.