Unterstützt PowerShell Konstanten?

118

Ich möchte einige ganzzahlige Konstanten in PowerShell deklarieren.

Gibt es eine gute Möglichkeit, das zu tun?

Tom Hazel
quelle

Antworten:

121

Verwenden

Set-Variable test -option Constant -value 100

oder

Set-Variable test -option ReadOnly -value 100

Der Unterschied zwischen "Constant" und "ReadOnly" besteht darin, dass eine schreibgeschützte Variable über entfernt (und dann neu erstellt) werden kann

Remove-Variable test -Force

Eine konstante Variable kann nicht entfernt werden (auch nicht mit -Force).

Weitere Informationen finden Sie in diesem TechNet-Artikel .

Motti Strom
quelle
4
Hmm, aber wie erzwingen Sie den Datentyp bei der Verwendung Set-Variable? Im Umgang mit Variablen kann man verwenden, [string]$name = valueaber das scheint für Konstanten nicht möglich zu sein?
Masi
8
@masi nur den Wert erzwingenSet-Variable test -option Constant -value [string]100
Monso
7
@Monso Sie benötigen Klammern um den Wert, wenn Sie den Typ wie angeben ([string]100). Siehe Antworten unten.
Polymorphix
15

Hier ist eine Lösung zum Definieren einer Konstanten wie dieser:

const myConst = 42

Lösung von http://poshcode.org/4063

    function Set-Constant {
  <#
    .SYNOPSIS
        Creates constants.
    .DESCRIPTION
        This function can help you to create constants so easy as it possible.
        It works as keyword 'const' as such as in C#.
    .EXAMPLE
        PS C:\> Set-Constant a = 10
        PS C:\> $a += 13

        There is a integer constant declaration, so the second line return
        error.
    .EXAMPLE
        PS C:\> const str = "this is a constant string"

        You also can use word 'const' for constant declaration. There is a
        string constant named '$str' in this example.
    .LINK
        Set-Variable
        About_Functions_Advanced_Parameters
  #>
  [CmdletBinding()]
  param(
    [Parameter(Mandatory=$true, Position=0)]
    [string][ValidateNotNullOrEmpty()]$Name,

    [Parameter(Mandatory=$true, Position=1)]
    [char][ValidateSet("=")]$Link,

    [Parameter(Mandatory=$true, Position=2)]
    [object][ValidateNotNullOrEmpty()]$Mean,

    [Parameter(Mandatory=$false)]
    [string]$Surround = "script"
  )

  Set-Variable -n $name -val $mean -opt Constant -s $surround
}

Set-Alias const Set-Constant
rauben
quelle
1
Leider funktioniert dies nicht, wenn Set-Constantes in einem Modul enthalten ist. Es wird eine Konstante im Modulbereich erstellt, in der sie Set-Constantenthalten ist. Als Workaround könnte man Parameter übergeben -Surround Global, aber das ist nicht immer erwünscht. Ich möchte eine Konstante in einem anderen Modul oder lokal in einer Funktion erstellen.
Zett42
11

Verwendung -option Constantmit dem Set-VariableCmdlet:

Set-Variable myvar -option Constant -value 100

Hat jetzt $myvareinen konstanten Wert von 100 und kann nicht geändert werden.

Paolo Tedesco
quelle
1
Wow, das ist klobig. Sie müssen Set-Variable verwenden, um es zu tun, nicht wahr?
Tom Hazel
Ja, es gibt keine unklare Möglichkeit, dies zu tun :)
Paolo Tedesco
1
Sie können auch vorhandene Variablen entweder mit set-variable (Alias ​​für sv) oder mit get-variable (gv) ändern und an der Options-Eigenschaft basteln.
x0n
Hmm, aber wie erzwingen Sie den Datentyp bei der Verwendung Set-Variable? Im Umgang mit Variablen kann man verwenden, [string]$name = valueaber das scheint für Konstanten nicht möglich zu sein?
Masi
@masi - siehe Mike Shepards Antwort an anderer Stelle auf dieser Seite. Kopieren und Einfügen von dort ist es:set-variable -name test -value ([int64]100) -option Constant
Chris J
11

Um einen bestimmten Werttyp, z. B. Int64, zu verwenden, können Sie den in set-variable verwendeten Wert explizit umwandeln.

Zum Beispiel:

set-variable -name test -value ([int64]100) -option Constant

Überprüfen,

$test | gm

Und Sie werden sehen, dass es sich um ein Int64 handelt (und nicht um Int32, was für den Wert 100 normal wäre).

Mike Shepard
quelle
5

Ich mag den syntaktischen Zucker, den Robs Antwort liefert:

const myConst = 42

Leider funktioniert seine Lösung nicht wie erwartet, wenn Sie die Set-ConstantFunktion in einem Modul definieren . Wenn es von außerhalb des Moduls aufgerufen Set-Constantwird, wird anstelle des Bereichs des Aufrufers eine Konstante im Modulbereich erstellt, in der es definiert ist . Dies macht die Konstante für den Anrufer unsichtbar.

Die folgende geänderte Funktion behebt dieses Problem. Die Lösung basiert auf dieser Antwort auf die Frage "Gibt es eine Möglichkeit für ein Powershell-Modul, in den Bereich seines Anrufers zu gelangen?" .

function Set-Constant {
    <#
    .SYNOPSIS
        Creates constants.
    .DESCRIPTION
        This function can help you to create constants so easy as it possible.
        It works as keyword 'const' as such as in C#.
    .EXAMPLE
        PS C:\> Set-Constant a = 10
        PS C:\> $a += 13

        There is a integer constant declaration, so the second line return
        error.
    .EXAMPLE
        PS C:\> const str = "this is a constant string"

        You also can use word 'const' for constant declaration. There is a
        string constant named '$str' in this example.
    .LINK
        Set-Variable
        About_Functions_Advanced_Parameters
    #>
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true, Position=0)] [string] [ValidateNotNullOrEmpty()] $Name,
        [Parameter(Mandatory=$true, Position=1)] [char] [ValidateSet("=")] $Link,
        [Parameter(Mandatory=$true, Position=2)] [object] [ValidateNotNullOrEmpty()] $Value
    )

    $var = New-Object System.Management.Automation.PSVariable -ArgumentList @(
        $Name, $Value, [System.Management.Automation.ScopedItemOptions]::Constant
    )

    $PSCmdlet.SessionState.PSVariable.Set( $var )
}

Set-Alias const Set-Constant

Anmerkungen:

  • Die Funktion funktioniert nur , wenn sie von außerhalb des Moduls aufgerufen wird, wo sie definiert ist. Dies ist der beabsichtigte Anwendungsfall, aber ich möchte eine Überprüfung hinzufügen, ob es vom selben Modul aufgerufen wird (in diesem Fall Set-Variable -scope 1sollte es funktionieren), wenn ich herausgefunden habe, wie das geht.
  • Ich habe den Parameter umbenannt -Meanzu -Value, für Konsistenz mit Set-Variable.
  • Die Funktion könnte erweitert werden , um die wahlweise eingestellt Private, ReadOnlyund AllScopeFahnen. Fügen Sie einfach die gewünschten Werte zum 3. Argument des PSVariableKonstruktors hinzu , das im obigen Skript durch aufgerufen wird New-Object.
zett42
quelle
-4

PowerShell v5.0 sollte dies zulassen

[statisch] [int] $ variable = 42

[statisch] [DateTime] $ heute

und dergleichen.

MarkH
quelle
2
funktioniert nicht unter ps 5.1. Typ [statisch] konnte nicht gefunden werden.
ThomasMX
5
Ganz zu schweigen davon, dass Statik nicht dasselbe ist wie eine Konstante
Kolob Canyon