Skip to content

Commit

Permalink
(MAINT) Clarify automatic vars in classes
Browse files Browse the repository at this point in the history
Prior to this change, the class documentation did not clearly explain
which automatic variables are available in class methods other than
the `$this` variable. This change adds the list of available automatic
variables and how to access them.

It also makes minor corrections to links and uses `Update-TypeData`
instead of `Add-Member` consistently. Finally, it explains examples
that were previously missing any information.
  • Loading branch information
michaeltlombardi authored and sdwheeler committed Nov 13, 2023
1 parent 2c837bc commit 11ebf9c
Show file tree
Hide file tree
Showing 16 changed files with 508 additions and 212 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: Describes how you can use classes to create your own custom types.
Locale: en-US
ms.date: 11/10/2023
ms.date: 11/13/2023
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes?view=powershell-5.1&WT.mc_id=ps-gethelp
schema: 2.0.0
title: about Classes
Expand Down Expand Up @@ -646,12 +646,12 @@ workaround for those limitations, if any.
- Directly declared properties can't define custom getter and setter
implementations.

Workaround: Define a hidden property and use `Add-Member` to define the
Workaround: Define a hidden property and use `Update-TypeData` to define the
visible getter and setter logic.
- Properties can't use the **Alias** attribute. The attribute only applies to
parameters, cmdlets, and functions.

Workaround: Use the `Add-Member` cmdlet to define aliases in the class
Workaround: Use the `Update-TypeData` cmdlet to define aliases in the class
constructors.
- When a PowerShell class is converted to JSON with the `ConvertTo-Json`
cmdlet, the output JSON includes all hidden properties and their values.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: Describes how to define constructors for PowerShell classes.
Locale: en-US
ms.date: 11/10/2023
ms.date: 11/13/2023
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes_constructors?view=powershell-5.1&WT.mc_id=ps-gethelp
schema: 2.0.0
title: about Classes Constructors
Expand Down Expand Up @@ -104,6 +104,13 @@ Name Author Pages PublishedOn
0 1/1/0001 12:00:00 AM
```

> [!NOTE]
> The default value for the **Name** and **Author** properties is `$null`
> because they're typed as strings, which is a reference type. The other
> properties have the default value for their defined type, because they're
> value type properties. For more information on the default values for
> properties, see ["Default property values" in about_Classes_Properties][03].
### Example 2 - Overriding the default constructor

**ExampleBook2** explicitly defines the default constructor, setting the values
Expand Down Expand Up @@ -205,6 +212,12 @@ default constructor isn't automatically added to the class.

### Example 4 - Chaining constructors with a shared method

This example shows how you can write reusable shared code for constructors.
PowerShell classes can't use constructor chaining, so this example class
defines an `Init()` method instead. The method has several overloads. The
overloads with fewer parameters call the more explicit overloads with default
values for the unspecified parameters.

```powershell
class ExampleBook4 {
[string] $Name
Expand Down Expand Up @@ -390,7 +403,7 @@ For derived classes that inherit from another class, the ordering is:

In all cases, static constructors only run once in a session.

For an example of constructor behavior and ordering, see [Example 5][05].
For an example of constructor behavior and ordering, see [Example 5][06].

## Hidden constructors

Expand All @@ -411,7 +424,7 @@ keyword. Hidden class constructors are:
> When you hide any constructor, the `new()` option is removed from
> IntelliSense and completion results.
For more information about the `hidden` keyword, see [about_Hidden][03].
For more information about the `hidden` keyword, see [about_Hidden][04].

## Static constructors

Expand Down Expand Up @@ -449,13 +462,13 @@ can be any of the following items:
- Any static value.
- Any expression that evaluates to a value of the parameter type.

For an example of constructors on a derived class, see [Example 5][05].
For an example of constructors on a derived class, see [Example 5][06].

## Chaining constructors

Unlike C#, PowerShell class constructors can't use chaining with the
`: this(<parameters>)` syntax. To reduce code duplication, use a hidden
`Init()` method with multiple overloads to the same effect. [Example 4][04]
`Init()` method with multiple overloads to the same effect. [Example 4][05]
shows a class using this pattern.

## Adding instance properties and methods with Update-TypeData
Expand Down Expand Up @@ -496,8 +509,8 @@ class <class-name> {
> be defined with `Update-TypeData`, like read-only properties.
For more information about defining instance methods with `Update-TypeData`,
see [about_Classes_Methods][06]. For more information about defining instance
properties with `Update-TypeData`, see [about_Classes_Properties][07].
see [about_Classes_Methods][07]. For more information about defining instance
properties with `Update-TypeData`, see [about_Classes_Properties][08].

## Limitations

Expand All @@ -523,19 +536,20 @@ PowerShell class constructors have the following limitations:

## See also

- [about_Classes][09]
- [about_Classes_Inheritance][10]
- [about_Classes][10]
- [about_Classes_Inheritance][11]
- [about_Classes_Methods][01]
- [about_Classes_Properties][08]
- [about_Classes_Properties][09]

<!-- Link reference definitions -->
[01]: about_Classes_Methods.md
[02]: #static-constructors
[03]: about_Hidden.md
[04]: #example-4---chaining-constructors-with-a-shared-method
[05]: #example-5---derived-class-constructors
[06]: about_Classes_Methods.md#defining-instance-methods-with-update-typedata
[07]: about_Classes_Properties.md#defining-instance-properties-with-update-typedata
[08]: about_Classes_Properties.md
[09]: about_Classes.md
[10]: about_Classes_Inheritance.md
[03]: about_Classes_Properties.md#default-property-values
[04]: about_Hidden.md
[05]: #example-4---chaining-constructors-with-a-shared-method
[06]: #example-5---derived-class-constructors
[07]: about_Classes_Methods.md#defining-instance-methods-with-update-typedata
[08]: about_Classes_Properties.md#defining-instance-properties-with-update-typedata
[09]: about_Classes_Properties.md
[10]: about_Classes.md
[11]: about_Classes_Inheritance.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: Describes how to define methods for PowerShell classes.
Locale: en-US
ms.date: 11/10/2023
ms.date: 11/13/2023
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes_methods?view=powershell-5.1&WT.mc_id=ps-gethelp
schema: 2.0.0
title: about Classes Methods
Expand Down Expand Up @@ -392,6 +392,60 @@ parameters:
For more information, see the
[Defining instance methods with Update-TypeData][06] section.

## Automatic variables in methods

Not all automatic variables are available in methods. The following list
includes automatic variables and suggestions for whether and how to use them in
PowerShell class methods. Automatic variables not included in the list aren't
available to class methods.

- `$?` - Access as normal.
- `$_` - Access as normal.
- `$args` - Use the explicit parameter variables instead.
- `$ConsoleFileName` - Access as `$Script:ConsoleFileName` instead.
- `$Error` - Access as normal.
- `$Event` - Access as normal.
- `$EventArgs` - Access as normal.
- `$EventSubscriber` - Access as normal.
- `$ExecutionContext` - Access as `$Script:ExecutionContext` instead.
- `$false` - Access as normal.
- `$foreach` - Access as normal.
- `$HOME` - Access as `$Script:HOME` instead.
- `$Host` - Access as `$Script:Host` instead.
- `$input` - Use the explicit parameter variables instead.
- `$LASTEXITCODE` - Access as normal.
- `$Matches` - Access as normal.
- `$MyInvocation` - Access as normal.
- `$NestedPromptLevel` - Access as normal.
- `$null` - Access as normal.
- `$PID` - Access as `$Script:PID` instead.
- `$PROFILE` - Access as `$Script:PROFILE` instead.
- `$PSBoundParameters` - Don't use this variable. It's intended for cmdlets and
functions. Using it in a class may have unexpected side effects.
- `$PSCmdlet` - Don't use this variable. It's intended for cmdlets and
functions. Using it in a class may have unexpected side effects.
- `$PSCommandPath` - Access as normal.
- `$PSCulture` - Access as `$Script:PSCulture` instead.
- `$PSEdition` - Access as `$Script:PSEdition` instead.
- `$PSHOME` - Access as `$Script:PSHOME` instead.
- `$PSItem` - Access as normal.
- `$PSScriptRoot` - Access as normal.
- `$PSSenderInfo` - Access as `$Script:PSSenderInfo` instead.
- `$PSUICulture` - Access as `$Script:PSUICulture` instead.
- `$PSVersionTable` - Access as `$Script:PSVersionTable` instead.
- `$PWD` - Access as normal.
- `$Sender` - Access as normal.
- `$ShellId` - Access as `$Script:ShellId` instead.
- `$StackTrace` - Access as normal.
- `$switch` - Access as normal.
- `$this` - Access as normal. In a class method, `$this` is always the current
instance of the class. You can access the class properties and methods with
it. It's not available in static methods.
- `$true` - Access as normal.

For more information about automatic variables, see
[about_Automatic_Variables][07].

## Hidden methods

You can hide methods of a class by declaring them with the `hidden` keyword.
Expand All @@ -410,7 +464,7 @@ Hidden class methods are:
> When you hide any overload for a method, that method is removed from
> IntelliSense, completion results, and the default output for `Get-Member`.
For more information about the `hidden` keyword, see [about_Hidden][07].
For more information about the `hidden` keyword, see [about_Hidden][08].

## Static methods

Expand Down Expand Up @@ -735,11 +789,12 @@ PowerShell class methods have the following limitations:

## See also

- [about_Classes][08]
- [about_Classes_Constructors][09]
- [about_Classes_Inheritance][10]
- [about_Classes_Properties][11]
- [about_Using][12]
- [about_Automatic_Variables][07]
- [about_Classes][09]
- [about_Classes_Constructors][10]
- [about_Classes_Inheritance][11]
- [about_Classes_Properties][12]
- [about_Using][13]

<!-- Link reference definitions -->
[01]: about_Preference_Variables.md
Expand All @@ -748,9 +803,10 @@ PowerShell class methods have the following limitations:
[04]: about_functions_advanced_parameters.md#parameter-and-variable-validation-attributes
[05]: #example-4---static-method-with-overloads
[06]: #defining-instance-methods-with-update-typedata
[07]: about_Hidden.md
[08]: about_Classes.md
[09]: about_Classes_Constructors.md
[10]: about_Classes_Inheritance.md
[11]: about_Classes_Properties.md
[12]: about_Using.md
[07]: about_Automatic_Variables.md
[08]: about_Hidden.md
[09]: about_Classes.md
[10]: about_Classes_Constructors.md
[11]: about_Classes_Inheritance.md
[12]: about_Classes_Properties.md
[13]: about_Using.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: Describes how to define properties for PowerShell classes.
Locale: en-US
ms.date: 11/10/2023
ms.date: 11/13/2023
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes_properties?view=powershell-5.1&WT.mc_id=ps-gethelp
schema: 2.0.0
title: about Classes Properties
Expand Down Expand Up @@ -654,7 +654,7 @@ text in angle brackets as needed.
class <ClassName> {
static [hashtable[]] $MemberDefinitions = @(
@{
Name = '<PropertyName>'
MemberName = '<PropertyName>'
MemberType = '<PropertyType>'
Value = <ValueDefinition>
}
Expand Down Expand Up @@ -684,7 +684,7 @@ The **Alias** attribute has no effect when used on a class property
declaration. PowerShell only uses that attribute to define aliases for cmdlet,
parameter, and function names.

To define an alias for a class property, use `Add-Member` with the
To define an alias for a class property, use `Update-TypeData` with the
`AliasProperty` **MemberType**.

For example, this definition of the **OperablePair** class defines two integer
Expand Down Expand Up @@ -753,12 +753,12 @@ $pair.RightHandSide = 2
### Defining calculated properties

To define a property that references the values of other properties, use the
`Add-Member` cmdlet with the `ScriptProperty` **MemberType**.
`Update-TypeData` cmdlet with the `ScriptProperty` **MemberType**.

For example, this definition of the **Budget** class defines the **Expenses**
and **Revenues** properties as arrays of floating-point numbers. It uses the
`Add-Member` cmdlet to define calculated properties for total expenses, total
revenues, and net income.
`Update-TypeData` cmdlet to define calculated properties for total expenses,
total revenues, and net income.

```powershell
class Budget {
Expand Down Expand Up @@ -824,8 +824,8 @@ Revenues : {2400, 2100, 4150}

PowerShell class properties can't define custom getter and setter logic
directly. You can approximate this functionality by defining a backing property
with the `hidden` keyword and using `Add-Member` to define a visible property
with custom logic for getting and setting the value.
with the `hidden` keyword and using `Update-TypeData` to define a visible
property with custom logic for getting and setting the value.

By convention, define the hidden backing property name with an underscore
prefix and use camel casing. For example, instead of `TaskCount`, name the
Expand Down Expand Up @@ -929,12 +929,12 @@ PowerShell class properties have the following limitations:
- Directly declared properties can't define custom getter and setter
implementations.

Workaround: Define a hidden property and use `Add-Member` to define the
Workaround: Define a hidden property and use `Update-TypeData` to define the
visible getter and setter logic.
- Properties can't use the **Alias** attribute. The attribute only applies to
parameters, cmdlets, and functions.

Workaround: Use the `Add-Member` cmdlet to define aliases in the class
Workaround: Use the `Update-TypeData` cmdlet to define aliases in the class
constructors.
- When a PowerShell class is converted to JSON with the `ConvertTo-Json`
cmdlet, the output JSON includes all hidden properties and their values.
Expand All @@ -943,10 +943,10 @@ PowerShell class properties have the following limitations:

## See also

- [about_Classes][09]
- [about_Classes_Constructors][10]
- [about_Classes_Inheritance][11]
- [about_Classes_Methods][12]
- [about_Classes][10]
- [about_Classes_Constructors][11]
- [about_Classes_Inheritance][12]
- [about_Classes_Methods][13]

[01]: #hidden-properties
[02]: #static-properties
Expand All @@ -955,9 +955,9 @@ PowerShell class properties have the following limitations:
[05]: /dotnet/csharp/language-reference/builtin-types/value-types
[06]: /dotnet/csharp/language-reference/builtin-types/default-values
[07]: about_Hidden.md
[09]: about_functions_advanced_parameters.md#parameter-and-variable-validation-attributes
[08]: about_Classes_Inheritance.md
[09]: about_Classes.md
[10]: about_Classes_Constructors.md
[11]: about_Classes_Inheritance.md
[12]: about_Classes_Methods.md
[09]: about_functions_advanced_parameters.md#parameter-and-variable-validation-attributes
[10]: about_Classes.md
[11]: about_Classes_Constructors.md
[12]: about_Classes_Inheritance.md
[13]: about_Classes_Methods.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: Describes how you can use classes to create your own custom types.
Locale: en-US
ms.date: 11/10/2023
ms.date: 11/13/2023
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_classes?view=powershell-7.2&WT.mc_id=ps-gethelp
schema: 2.0.0
title: about Classes
Expand Down Expand Up @@ -643,12 +643,12 @@ workaround for those limitations, if any.
- Directly declared properties can't define custom getter and setter
implementations.

Workaround: Define a hidden property and use `Add-Member` to define the
Workaround: Define a hidden property and use `Update-TypeData` to define the
visible getter and setter logic.
- Properties can't use the **Alias** attribute. The attribute only applies to
parameters, cmdlets, and functions.

Workaround: Use the `Add-Member` cmdlet to define aliases in the class
Workaround: Use the `Update-TypeData` cmdlet to define aliases in the class
constructors.
- When a PowerShell class is converted to JSON with the `ConvertTo-Json`
cmdlet, the output JSON includes all hidden properties and their values.
Expand Down
Loading

0 comments on commit 11ebf9c

Please sign in to comment.