Meta-issue to track work on improving the experience of PowerShell class usage as much as possible.
Note on By-Design Behaviours
PowerShell classes currently are a bit finnicky. Some of this is a necessary pain because of the design constraints behind classes.
Classes are currently implemented as compiling to .NET IL so that we can take advantage of the .NET object model. Not doing this would mean us reinventing (and having to maintain) the wheel on essentially all object-oriented features available in .NET (or anywhere else) and paying a high runtime overhead on shimming compatibility with the .NET object model (e.g. faking inheritance from .NET classes).
Instead, we compile PowerShell classes to dynamic assemblies and bake in calls to PowerShell in the generated IL. To do this at runtime would mean either breaking dynamic- and module-scoped behaviours in classes, or emitting a new dynamic assembly every time we hit a class definition (and since PowerShell's highest compilation unit is the scriptblock, and scriptblocks are permitted in for-loops, the performance penalty here could be extreme). (I'm still a bit hazy on the details about the mechanisms here, especially in terms of why caching is made impossible by module scope or in comparison to Add-Type, but @daxian-dbw or @lzybkr will be able to add to/correct me).
The need to compile classes at parse-time means the types required to define a class (in IL) must also be known at parse-time. The module-scoping issue means that a using module statement is required to import classes from modules (@daxian-dbw might like to add information here about the specifics governing this need), or by exporting class usage in PowerShell functions (classes having a sort of module-private behaviour).
Issues to Improve
There are, however, a few improvements possible to PowerShell classes that might not run up against the design constraints given above. Below is a list of open issues for classes in PowerShell.
Classes in modules
Type errors
Other bugs
New feature requests
A couple of other resources on these issues:
Meta-issue to track work on improving the experience of PowerShell class usage as much as possible.
Note on By-Design Behaviours
PowerShell classes currently are a bit finnicky. Some of this is a necessary pain because of the design constraints behind classes.
Classes are currently implemented as compiling to .NET IL so that we can take advantage of the .NET object model. Not doing this would mean us reinventing (and having to maintain) the wheel on essentially all object-oriented features available in .NET (or anywhere else) and paying a high runtime overhead on shimming compatibility with the .NET object model (e.g. faking inheritance from .NET classes).
Instead, we compile PowerShell classes to dynamic assemblies and bake in calls to PowerShell in the generated IL. To do this at runtime would mean either breaking dynamic- and module-scoped behaviours in classes, or emitting a new dynamic assembly every time we hit a class definition (and since PowerShell's highest compilation unit is the scriptblock, and scriptblocks are permitted in for-loops, the performance penalty here could be extreme). (I'm still a bit hazy on the details about the mechanisms here, especially in terms of why caching is made impossible by module scope or in comparison to
Add-Type, but @daxian-dbw or @lzybkr will be able to add to/correct me).The need to compile classes at parse-time means the types required to define a class (in IL) must also be known at parse-time. The module-scoping issue means that a
using modulestatement is required to import classes from modules (@daxian-dbw might like to add information here about the specifics governing this need), or by exporting class usage in PowerShell functions (classes having a sort of module-private behaviour).Issues to Improve
There are, however, a few improvements possible to PowerShell classes that might not run up against the design constraints given above. Below is a list of open issues for classes in PowerShell.
Classes in modules
Import-Module -Force.ScriptsToProcesswithusing modulestops classes from being importedusing moduleimports nested module classes in a script but not interactively.using module testdoesn't load the powershell class defined in 'test' if 'test.psd1' has 'FunctionToExport' or 'CmdletToExport' specified #4112using moduledoesn't load classes whenFunctionToExportorCmdletToExportare specified in the.psd1using module testcan only load the classes defined intest.psm1but not other .psm1 files #4114using moduledoes not find classes in nested modules.New-Moduleproblem).Type errors
Using external types / classes in Custom PowerShell Classes (v5) results in Parsing Error #2074 Types not available at parse-time used in PS class bodies cause parse errors. @daxian-dbw noted that we need some types at parse-time (such as method return type) to generate the IL, but type resolution inside method/constructor scriptblocks may not be needed and be more appropriate at runtime.Noted as by design.Other bugs
New-Objectdoes not work for PS classes as it does for .NET classes.protected internalmethod of base class. #7622protected internaloverride doesn't work (program diverges on method call).New feature requests
static externmethods and struct definition in PowerShelluse static <class>usage to allow static member access in PowerShell #5099 Static class member importsenumtypes other thanInt32A couple of other resources on these issues:
usingstatement: here.