Share via


about_Classes_Properties

Descrizione breve

Viene descritto come definire le proprietà per le classi di PowerShell.

Descrizione lunga

Le proprietà sono membri della classe che contengono dati. Le proprietà vengono dichiarate come variabili nell'ambito della classe. Una proprietà può essere di qualsiasi tipo predefinito o di un'istanza di un'altra classe. Le classi possono essere pari a zero o più proprietà. Le classi non hanno un numero massimo di proprietà.

Le proprietà della classe possono avere un numero qualsiasi di attributi, inclusi gli attributi nascosti e statici . Ogni definizione di proprietà deve includere un tipo per la proprietà . È possibile definire un valore predefinito per una proprietà.

Sintassi

Le proprietà della classe usano le sintassi seguenti:

Sintassi a una riga

[[<attribute>]...] [<property-type>] $<property-name> [= <default-value>]

Sintassi multilinea

[[<attribute>]...]
[<property-type>]
$<property-name> [= <default-value>]

Esempi

Esempio 1 - Proprietà minime della classe

Le proprietà della classe ExampleProject1 usano tipi predefiniti senza attributi o valori predefiniti.

class ExampleProject1 {
    [string]   $Name
    [int]      $Size
    [bool]     $Completed
    [string]   $Assignee
    [datetime] $StartDate
    [datetime] $EndDate
    [datetime] $DueDate
}

[ExampleProject1]::new()

$null -eq ([ExampleProject1]::new()).Name
Name      :
Size      : 0
Completed : False
StartDate : 1/1/0001 12:00:00 AM
EndDate   : 1/1/0001 12:00:00 AM
DueDate   : 1/1/0001 12:00:00 AM

True

Il valore predefinito per le proprietà Name e Assignee è $null dovuto al fatto che vengono digitati come stringhe, ovvero un tipo riferimento. Le altre proprietà hanno il valore predefinito per il tipo definito, perché sono proprietà del tipo valore. Per altre informazioni sui valori predefiniti per le proprietà, vedere Valori delle proprietà predefinite.

Esempio 2 - Proprietà della classe con tipi personalizzati

Le proprietà per ExampleProject2 includono un'enumerazione personalizzata e una classe definita in PowerShell prima della classe ExampleProject2 .

enum ProjectState {
    NotTriaged
    ReadyForWork
    Committed
    Blocked
    InProgress
    Done
}

class ProjectAssignee {
    [string] $DisplayName
    [string] $UserName

    [string] ToString() {
        return "$($this.DisplayName) ($($this.UserName))"
    }
}

class ExampleProject2 {
    [string]          $Name
    [int]             $Size
    [ProjectState]    $State
    [ProjectAssignee] $Assignee
    [datetime]        $StartDate
    [datetime]        $EndDate
    [datetime]        $DueDate
}

[ExampleProject2]@{
    Name     = 'Class Property Documentation'
    Size     = 8
    State    = 'InProgress'
    Assignee = @{
        DisplayName = 'Mikey Lombardi'
        UserName    = 'michaeltlombardi'
    }
    StartDate = '2023-10-23'
    DueDate   = '2023-10-27'
}
Name      : Class Property Documentation
Size      : 8
State     : InProgress
Assignee  : Mikey Lombardi (michaeltlombardi)
StartDate : 10/23/2023 12:00:00 AM
EndDate   : 1/1/0001 12:00:00 AM
DueDate   : 10/27/2023 12:00:00 AM

Esempio 3 - Proprietà class con un attributo di convalida

La classe ExampleProject3 definisce la proprietà Size come numero intero che deve essere maggiore o uguale a 0 e minore o uguale a 16. Usa l'attributo ValidateRange per limitare il valore.

class ExampleProject3 {
                           [string]   $Name
    [ValidateRange(0, 16)] [int]      $Size
                           [bool]     $Completed
                           [string]   $Assignee
                           [datetime] $StartDate
                           [datetime] $EndDate
                           [datetime] $DueDate
}

$project = [ExampleProject3]::new()
$project
Name      :
Size      : 0
Completed : False
Assignee  :
StartDate : 1/1/0001 12:00:00 AM
EndDate   : 1/1/0001 12:00:00 AM
DueDate   : 1/1/0001 12:00:00 AM

Quando viene creata un'istanza di ExampleProject3 , per impostazione predefinita Size viene impostato su 0. Se si imposta la proprietà su un valore all'interno dell'intervallo valido, il valore viene aggiornato.

$project.Size = 8
$project
Name      :
Size      : 8
Completed : False
Assignee  :
StartDate : 1/1/0001 12:00:00 AM
EndDate   : 1/1/0001 12:00:00 AM
DueDate   : 1/1/0001 12:00:00 AM

Quando Size è impostato su un valore non valido all'esterno dell'intervallo, PowerShell genera un'eccezione e il valore non viene modificato.

$project.Size = 32
$project.Size = -1

$project
Exception setting "Size": "The 32 argument is greater than the maximum
allowed range of 16. Supply an argument that is less than or equal to 16
and then try the command again."
At line:1 char:1
+ $project.Size = 32
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationExc
   eption
    + FullyQualifiedErrorId : ExceptionWhenSetting

Exception setting "Size": "The -1 argument is less than the minimum
allowed range of 0. Supply an argument that is greater than or equal to 0
and then try the command again."
At line:1 char:1
+ $project.Size = -1
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationExc
   eption
    + FullyQualifiedErrorId : ExceptionWhenSetting

Name      :
Size      : 8
Completed : False
Assignee  :
StartDate : 1/1/0001 12:00:00 AM
EndDate   : 1/1/0001 12:00:00 AM
DueDate   : 1/1/0001 12:00:00 AM

Esempio 4 - Proprietà class con un valore predefinito esplicito

La classe ExampleProject4 imposta il valore predefinito per la proprietà StartDate sulla data corrente.

class ExampleProject4 {
    [string]   $Name
    [int]      $Size
    [bool]     $Completed
    [string]   $Assignee
    [datetime] $StartDate = (Get-Date).Date
    [datetime] $EndDate
    [datetime] $DueDate
}

[ExampleProject4]::new()

[ExampleProject4]::new().StartDate -eq (Get-Date).Date
Name      :
Size      : 0
Completed : False
Assignee  :
StartDate : 10/23/2023 12:00:00 AM
EndDate   : 1/1/0001 12:00:00 AM
DueDate   : 1/1/0001 12:00:00 AM

True

Esempio 5 - Proprietà della classe Hidden

La proprietà Guid della classe ExampleProject5 ha la hidden parola chiave . La proprietà Guid non viene visualizzata nell'output predefinito per la classe o nell'elenco delle proprietà restituite da Get-Member.

class ExampleProject5 {
           [string]   $Name
           [int]      $Size
           [bool]     $Completed
           [string]   $Assignee
           [datetime] $StartDate
           [datetime] $EndDate
           [datetime] $DueDate
    hidden [string]   $Guid      = (New-Guid).Guid
}

$project = [ExampleProject5]::new()

"Project GUID: $($project.Guid)"

$project

$project | Get-Member -MemberType Properties | Format-Table
Project GUID: c72cef84-057c-4649-8940-13490dcf72f0

Name      :
Size      : 0
Completed : False
Assignee  :
StartDate : 1/1/0001 12:00:00 AM
EndDate   : 1/1/0001 12:00:00 AM
DueDate   : 1/1/0001 12:00:00 AM


   TypeName: ExampleProject5

Name      MemberType Definition
----      ---------- ----------
Assignee  Property   string Assignee {get;set;}
Completed Property   bool Completed {get;set;}
DueDate   Property   datetime DueDate {get;set;}
EndDate   Property   datetime EndDate {get;set;}
Name      Property   string Name {get;set;}
Size      Property   int Size {get;set;}
StartDate Property   datetime StartDate {get;set;}

Esempio 6 - Proprietà della classe statica

La classe ExampleProject6 definisce la proprietà Static Projects come elenco di tutti i progetti creati. Il costruttore predefinito per la classe aggiunge la nuova istanza all'elenco di progetti.

class ExampleProject6 {
           [string]            $Name
           [int]               $Size
           [bool]              $Completed
           [string]            $Assignee
           [datetime]          $StartDate
           [datetime]          $EndDate
           [datetime]          $DueDate
    hidden [string]            $Guid     = (New-Guid).Guid
    static [ExampleProject6[]] $Projects = @()

    ExampleProject6() {
        [ExampleProject6]::Projects += $this
    }
}

"Project Count: $([ExampleProject6]::Projects.Count)"

$project1 = [ExampleProject6]@{ Name = 'Project_1' }
$project2 = [ExampleProject6]@{ Name = 'Project_2' }

[ExampleProject6]::Projects | Select-Object -Property Name, Guid
Project Count: 0

Name      Guid
----      ----
Project_1 75e7c8a0-f8d1-433a-a5be-fd7249494694
Project_2 6c501be4-e68c-4df5-8fce-e49dd8366afe

Esempio 7- Definizione di una proprietà nel costruttore

La classe ExampleProject7 definisce la proprietà script Duration nel costruttore della classe statica con il Update-TypeData cmdlet . L'uso del Update-TypeData cmdlet o Add-Member è l'unico modo per definire proprietà avanzate per le classi di PowerShell.

La proprietà Duration restituisce un valore di $null a meno che non siano impostate entrambe le proprietà StartDate e EndDate e StartDate sia definito come precedente a EndDate.

class ExampleProject7 {
    [string]   $Name
    [int]      $Size
    [bool]     $Completed
    [string]   $Assignee
    [datetime] $StartDate
    [datetime] $EndDate
    [datetime] $DueDate

    static [hashtable[]] $MemberDefinitions = @(
        @{
            MemberName = 'Duration'
            MemberType = 'ScriptProperty'
            Value      = {
                [datetime]$UnsetDate = 0

                $StartNotSet   = $this.StartDate -eq $UnsetDate
                $EndNotSet     = $this.EndDate   -eq $UnsetDate
                $StartAfterEnd = $this.StartDate -gt $this.EndDate

                if ($StartNotSet -or $EndNotSet -or $StartAfterEnd) {
                    return $null
                }

                return $this.EndDate - $this.StartDate
            }
        }
    )

    static ExampleProject7() {
        $TypeName = [ExampleProject7].Name
        foreach ($Definition in [ExampleProject7]::MemberDefinitions) {
            Update-TypeData -TypeName $TypeName @Definition
        }
    }

    ExampleProject7() {}

    ExampleProject7([string]$Name) {
        $this.Name = $Name
    }
}

$Project = [ExampleProject7]::new()
$Project

$null -eq $Project.Duration
Duration  :
Name      :
Size      : 0
Completed : False
Assignee  :
StartDate : 1/1/0001 12:00:00 AM
EndDate   : 1/1/0001 12:00:00 AM
DueDate   : 1/1/0001 12:00:00 AM

True

La visualizzazione predefinita per un'istanza della classe ExampleProject7 include la durata. Poiché le proprietà StartDate e EndDate non sono impostate, la proprietà Duration è $null.

$Project.StartDate = '2023-01-01'
$Project.EndDate   = '2023-01-08'

$Project
Duration  : 7.00:00:00
Name      :
Size      : 0
Completed : False
Assignee  :
StartDate : 1/1/2023 12:00:00 AM
EndDate   : 1/8/2023 12:00:00 AM
DueDate   : 1/1/0001 12:00:00 AM

Con le proprietà impostate correttamente, la proprietà Duration restituisce un intervallo di tempo che rappresenta la durata dell'esecuzione del progetto.

Valori di proprietà predefiniti

Ogni proprietà della classe ha un valore predefinito implicito a seconda del tipo della proprietà.

Se una proprietà è un tipo riferimento, ad esempio una stringa o un oggetto, il valore predefinito implicito è $null. Se una proprietà è un tipo valore, ad esempio un numero, un valore booleano o un'enumerazione, la proprietà ha un valore predefinito a seconda del tipo:

  • Tipi numerici, ad esempio numeri interi e numeri a virgola mobile, per impostazione predefinita 0
  • Valori booleani predefiniti $false
  • Per impostazione predefinita 0, le enumerazioni sono , anche l'enumerazione non definisce un'etichetta per 0.

Per altre informazioni sui valori predefiniti in .NET, vedere Valori predefiniti dei tipi C# (Riferimenti per C#).

Per definire un valore predefinito esplicito per una proprietà, dichiarare la proprietà con un'assegnazione al valore predefinito.

Ad esempio, questa definizione per la classe ProjectTask definisce un valore predefinito esplicito per la proprietà Guid , assegnando un GUID casuale a ogni nuova istanza.

class ProjectTask {
    [string] $Name
    [string] $Description
    [string] $Guid = (New-Guid).Guid
}

[ProjectTask]::new()
Name Description Guid
---- ----------- ----
                 aa96350c-358d-465c-96d1-a49949219eec

Anche le proprietà nascoste e statiche possono avere valori predefiniti.

Proprietà nascoste

È possibile nascondere le proprietà di una classe dichiarandole con la hidden parola chiave . Le proprietà della classe nascoste sono:

  • Non incluso nell'output predefinito per la classe .
  • Non incluso nell'elenco dei membri della classe restituiti dal Get-Member cmdlet . Per visualizzare le proprietà nascoste con Get-Member, usare il parametro Force .
  • Non visualizzato in completamento tramite tabulazione o IntelliSense, a meno che il completamento non si verifichi nella classe che definisce la proprietà nascosta.
  • Membri pubblici della classe . È possibile accedervi e modificarli. Nascondere una proprietà non lo rende privato. Nasconde solo la proprietà come descritto nei punti precedenti.

Per altre informazioni sulla hidden parola chiave, vedere about_Hidden.

Proprietà statiche

È possibile definire una proprietà come appartenente alla classe stessa anziché alle istanze della classe dichiarando la proprietà con la static parola chiave . Proprietà della classe statica:

  • Sono sempre disponibili, indipendentemente dalla creazione di istanze della classe.
  • Vengono condivisi tra tutte le istanze della classe .
  • Sono sempre disponibili.
  • Sono modificabili. È possibile aggiornare le proprietà statiche. Non sono modificabili per impostazione predefinita.
  • Live per l'intero intervallo di sessione.

Importante

Le proprietà statiche per le classi definite in PowerShell non sono modificabili. Possono

Proprietà della classe derivata

Quando una classe deriva da una classe di base, eredita le proprietà della classe base. Tutte le proprietà definite nella classe base, incluse le proprietà nascoste, sono disponibili nella classe derivata.

Una classe derivata può eseguire l'override di una proprietà ereditata definendola nella definizione della classe. La proprietà nella classe derivata utilizza il tipo ridefinito e il valore predefinito, se presenti. Se la proprietà ereditata ha definito un valore predefinito e la proprietà ridefinita non ha alcun valore predefinito.

Se una classe derivata non esegue l'override di una proprietà statica, l'accesso alla proprietà statica tramite la classe derivata accede alla proprietà statica della classe base. La modifica del valore della proprietà tramite la classe derivata modifica il valore nella classe base. Qualsiasi altra classe derivata che non esegue l'override della proprietà statica usa anche il valore della proprietà nella classe di base. L'aggiornamento del valore di una proprietà statica ereditata in una classe che non esegue l'override della proprietà potrebbe avere effetti imprevisti per le classi derivate dalla stessa classe di base.

Nell'esempio seguente viene illustrato il comportamento per le proprietà statiche e dell'istanza nelle classi derivate.

class BaseClass {
    static [string] $StaticProperty = 'Static'
    [string] $InstanceProperty = 'Instance'
}
class DerivedClassA : BaseClass     {}
class DerivedClassB : BaseClass     {}
class DerivedClassC : DerivedClassB {
    [string] $InstanceProperty
}
class DerivedClassD : BaseClass {
    static [string] $StaticProperty = 'Override'
    [string] $InstanceProperty = 'Override'
}

"Base instance      => $([BaseClass]::new().InstanceProperty)"
"Derived instance A => $([DerivedClassA]::new().InstanceProperty)"
"Derived instance B => $([DerivedClassB]::new().InstanceProperty)"
"Derived instance C => $([DerivedClassC]::new().InstanceProperty)"
"Derived instance D => $([DerivedClassD]::new().InstanceProperty)"
Base instance      => Instance
Derived instance A => Instance
Derived instance B => Instance
Derived instance C =>
Derived instance D => Override

InstanceProperty per DerivedClassC è una stringa vuota perché la classe ha ridefinito la proprietà senza impostare un valore predefinito. Per DerivedClassD il valore è Override dovuto al fatto che la classe ha ridefinito la proprietà con tale stringa come valore predefinito.

"Base static        => $([BaseClass]::StaticProperty)"
"Derived static A   => $([DerivedClassA]::StaticProperty)"
"Derived static B   => $([DerivedClassB]::StaticProperty)"
"Derived static C   => $([DerivedClassC]::StaticProperty)"
"Derived static D   => $([DerivedClassD]::StaticProperty)"
Base static        => Static
Derived static A   => Static
Derived static B   => Static
Derived static C   => Static
Derived static D   => Override

Ad eccezione di DerivedClassD, il valore della proprietà statica per le classi derivate è uguale alla classe di base, perché non ridefiniscono la proprietà. Questo vale anche per DerivedClassC, che eredita da DerivedClassB anziché direttamente da BaseClass.

[DerivedClassA]::StaticProperty = 'Updated from A'
"Base static        => $([BaseClass]::StaticProperty)"
"Derived static A   => $([DerivedClassA]::StaticProperty)"
"Derived static B   => $([DerivedClassB]::StaticProperty)"
"Derived static C   => $([DerivedClassC]::StaticProperty)"
"Derived static D   => $([DerivedClassD]::StaticProperty)"
Base static        => Updated from A
Derived static A   => Updated from A
Derived static B   => Updated from A
Derived static C   => Updated from A
Derived static D   => Override

Quando si accede a StaticProperty e si modifica tramite DerivedClassA, il valore modificato influisce su ogni classe ad eccezione di DerivedClassD.

Per altre informazioni sull'ereditarietà delle classi, incluso un esempio completo, vedere about_Classes_Inheritance.

Uso degli attributi delle proprietà

PowerShell include diverse classi di attributi che è possibile usare per migliorare le informazioni sul tipo di dati e convalidare i dati assegnati a una proprietà. Gli attributi di convalida consentono di verificare che i valori assegnati alle proprietà soddisfino i requisiti definiti. La convalida viene attivata nel momento in cui viene assegnato il valore.

Per altre informazioni sugli attributi disponibili, vedere about_Functions_Advanced_Parameters.

Definizione delle proprietà dell'istanza con Update-TypeData

Oltre a dichiarare le proprietà direttamente nella definizione della classe, è possibile definire le proprietà per le istanze di una classe nel costruttore statico usando il Update-TypeData cmdlet .

Usare questo frammento di codice come punto di partenza per il modello. Sostituire il testo segnaposto tra parentesi angolari in base alle esigenze.

class <ClassName> {
    static [hashtable[]] $MemberDefinitions = @(
        @{
            MemberName = '<PropertyName>'
            MemberType = '<PropertyType>'
            Value      = <ValueDefinition>
        }
    )

    static <ClassName>() {
        $TypeName = [<ClassName>].Name
        foreach ($Definition in [<ClassName>]::MemberDefinitions) {
            Update-TypeData -TypeName $TypeName @Definition
        }
    }
}

Suggerimento

Il Add-Member cmdlet può aggiungere proprietà e metodi a una classe in costruttori non statici, ma il cmdlet viene eseguito ogni volta che viene chiamato il costruttore. L'uso Update-TypeData nel costruttore statico garantisce che il codice per l'aggiunta dei membri alla classe debba essere eseguito una sola volta in una sessione.

Aggiungere proprietà alla classe solo in costruttori non statici quando non possono essere definite con Update-TypeData, ad esempio le proprietà di sola lettura.

Definizione delle proprietà alias

L'attributo Alias non ha alcun effetto quando viene usato per una dichiarazione di proprietà di classe. PowerShell usa solo tale attributo per definire alias per i nomi di cmdlet, parametri e funzioni.

Per definire un alias per una proprietà di classe, utilizzare Update-TypeData con MemberTypeAliasProperty.

Ad esempio, questa definizione della classe OperablePair definisce due proprietà integer x e y rispettivamente con gli alias LeftHandSide e RightHandSide .

class OperablePair {
    [int] $x
    [int] $y

    static [hashtable[]] $MemberDefinitions = @(
            @{
                MemberType = 'AliasProperty'
                MemberName = 'LeftHandSide'
                Value      = 'x'
            }
            @{
                MemberType = 'AliasProperty'
                MemberName = 'RightHandSide'
                Value      = 'y'
            }
    )

    static OperablePair() {
        $TypeName = [OperablePair].Name
        foreach ($Definition in [OperablePair]::MemberDefinitions) {
            Update-TypeData -TypeName $TypeName @Definition
        }
    }

    OperablePair() {}

    OperablePair([int]$x, [int]$y) {
        $this.x = $x
        $this.y = $y
    }

    # Math methods for the pair of values
    [int]   GetSum()        { return $this.x + $this.y }
    [int]   GetProduct()    { return $this.x * $this.y }
    [int]   GetDifference() { return $this.x - $this.y }
    [float] GetQuotient()   { return $this.x / $this.y }
    [int]   GetModulus()    { return $this.x % $this.y }
}

Con gli alias definiti, gli utenti possono accedere alle proprietà con uno dei due nomi.

$pair = [OperablePair]@{ x = 8 ; RightHandSide = 3 }

"$($pair.x) % $($pair.y) = $($pair.GetModulus())"

$pair.LeftHandSide  = 3
$pair.RightHandSide = 2
"$($pair.x) x $($pair.y) = $($pair.GetProduct())"
8 % 3 = 2

3 x 2 = 6

Definizione delle proprietà calcolate

Per definire una proprietà che fa riferimento ai valori di altre proprietà, utilizzare il Update-TypeData cmdlet con ScriptPropertyMemberType.

Ad esempio, questa definizione della classe Budget definisce le proprietà Expenses e Revenue come matrici di numeri a virgola mobile. Usa il Update-TypeData cmdlet per definire le proprietà calcolate per le spese totali, i ricavi totali e il reddito netto.

class Budget {
    [float[]] $Expenses
    [float[]] $Revenues

    static [hashtable[]] $MemberDefinitions = @(
        @{
            MemberType = 'ScriptProperty'
            MemberName = 'TotalExpenses'
            Value      = { ($this.Expenses | Measure-Object -Sum).Sum }
        }
        @{
            MemberType = 'ScriptProperty'
            MemberName = 'TotalRevenues'
            Value      = { ($this.Revenues | Measure-Object -Sum).Sum }
        }
        @{
            MemberType = 'ScriptProperty'
            MemberName = 'NetIncome'
            Value      = { $this.TotalRevenues - $this.TotalExpenses }
        }
    )

    static Budget() {
        $TypeName = [Budget].Name
        foreach ($Definition in [Budget]::MemberDefinitions) {
            Update-TypeData -TypeName $TypeName @Definition
        }
    }

    Budget() {}

    Budget($Expenses, $Revenues) {
        $this.Expenses = $Expenses
        $this.Revenues = $Revenues
    }
}

[Budget]::new()

[Budget]@{
    Expenses = @(2500, 1931, 3700)
    Revenues = @(2400, 2100, 4150)
}
TotalExpenses : 0
TotalRevenues : 0
NetIncome     : 0
Expenses      :
Revenues      :

TotalExpenses : 8131
TotalRevenues : 8650
NetIncome     : 519
Expenses      : {2500, 1931, 3700}
Revenues      : {2400, 2100, 4150}

Definizione delle proprietà con la logica get e set personalizzata

Le proprietà della classe PowerShell non possono definire direttamente la logica getter e setter personalizzata. È possibile approssimare questa funzionalità definendo una proprietà di backup con la hidden parola chiave e usando Update-TypeData per definire una proprietà visibile con logica personalizzata per ottenere e impostare il valore.

Per convenzione, definire il nome della proprietà nascosto sottostante con un prefisso di sottolineatura e usare maiuscole e minuscole camel. Ad esempio, anziché TaskCount, denominare la proprietà _taskCountnascosto di backup .

In questo esempio la classe ProjectSize definisce una proprietà integer nascosta denominata _value. Definisce Value come oggetto con logica ScriptProperty personalizzata per ottenere e impostare la proprietà _value . Lo scriptblock setter gestisce la conversione della rappresentazione di stringa del progetto nella dimensione corretta.

class ProjectSize {
    hidden [ValidateSet(0, 1, 2, 3)] [int] $_value

    static [hashtable[]] $MemberDefinitions = @(
        @{
            MemberType  = 'ScriptProperty'
            MemberName  = 'Value'
            Value       = { $this._value } # Getter
            SecondValue = {                # Setter
                $ProposedValue = $args[0]

                if ($ProposedValue -is [string]) {
                    switch ($ProposedValue) {
                        'Small'  { $this._value = 1 ; break }
                        'Medium' { $this._value = 2 ; break }
                        'Large'  { $this._value = 3 ; break }
                        default  { throw "Unknown size '$ProposedValue'" }
                    }
                } else {
                    $this._value = $ProposedValue
                }
            }
        }
    )

    static ProjectSize() {
        $TypeName = [ProjectSize].Name
        foreach ($Definition in [ProjectSize]::MemberDefinitions) {
            Update-TypeData -TypeName $TypeName @Definition
        }
    }

    ProjectSize()              {}
    ProjectSize([int]$Size)    { $this.Value = $Size }
    ProjectSize([string]$Size) { $this.Value = $Size }

    [string] ToString() {
        $Output = switch ($this._value) {
            1       { 'Small'     }
            2       { 'Medium'    }
            3       { 'Large'     }
            default { 'Undefined' }
        }

        return $Output
    }
}

Con il getter personalizzato e il setter definiti, è possibile impostare la proprietà Value come numero intero o stringa.

$size = [ProjectSize]::new()
"The initial size is: $($size._value), $size"

$size.Value = 1
"The defined size is: $($size._value), $size"

$Size.Value += 1
"The updated size is: $($size._value), $size"

$Size.Value = 'Large'
"The final size is:   $($size._value), $size"
The initial size is: 0, Undefined

The defined size is: 1, Small

The updated size is: 2, Medium

The final size is:   3, Large

Limiti

Le proprietà della classe PowerShell presentano le limitazioni seguenti:

  • Le proprietà statiche sono sempre modificabili. Le classi di PowerShell non possono definire proprietà statiche non modificabili.

    Soluzione alternativa: nessuna.

  • Le proprietà non possono usare l'attributo ValidateScript, perché gli argomenti dell'attributo della proprietà della classe devono essere costanti.

    Soluzione alternativa: definire una classe che eredita dal tipo ValidateArgumentsAttribute e usare tale attributo.

  • Le proprietà dichiarate direttamente non possono definire implementazioni getter e setter personalizzate.

    Soluzione alternativa: definire una proprietà nascosta e usare Update-TypeData per definire la logica getter e setter visibile.

  • Le proprietà non possono usare l'attributo Alias . L'attributo si applica solo a parametri, cmdlet e funzioni.

    Soluzione alternativa: usare il Update-TypeData cmdlet per definire gli alias nei costruttori della classe.

  • Quando una classe di PowerShell viene convertita in JSON con il ConvertTo-Json cmdlet , il codice JSON di output include tutte le proprietà nascoste e i relativi valori.

    Soluzione alternativa: nessuna

Vedi anche