Поделиться через


about_Classes_Methods

Краткое описание

Описывает, как определить методы для классов PowerShell.

Подробное описание

Методы определяют действия, которые может выполнить класс. Методы могут принимать параметры, указывающие входные данные. Методы всегда определяют тип выходных данных. Если метод не возвращает никаких выходных данных, он должен иметь тип выходных данных Void . Если метод не определяет тип выходных данных явным образом, тип выходных данных метода — Void.

В методах класса никакие объекты не отправляются в конвейер, за исключением объектов, указанных в инструкции return . Случайные выходные данные конвейера из кода отсутствуют.

Примечание

Это принципиально отличается от того, как функции PowerShell обрабатывают выходные данные, когда все передается в конвейер.

Неустранимые ошибки, записанные в поток ошибок из метода класса, не передаются. Необходимо использовать для throw отображения устранимой ошибки. Write-* С помощью командлетов можно по-прежнему выполнять запись в потоки вывода PowerShell из метода класса. Командлеты учитывают переменные предпочтения в вызывающей область. Однако следует избегать использования Write-* командлетов, чтобы метод выводили только объекты с помощью инструкции return .

Методы класса могут ссылаться на текущий экземпляр объекта класса, используя автоматическую $this переменную для доступа к свойствам и другим методам, определенным в текущем классе. Автоматическая $this переменная недоступна в статических методах.

Методы класса могут иметь любое количество атрибутов, включая скрытые и статические атрибуты.

Синтаксис

Методы класса используют следующий синтаксис:

Однострочный синтаксис

[[<attribute>]...] [hidden] [static] [<output-type>] <method-name> ([<method-parameters>]) { <body> }

Многостроковый синтаксис

[[<attribute>]...]
[hidden]
[static]
[<output-type>] <method-name> ([<method-parameters>]) {
  <body>
}

Примеры

Пример 1. Минимальное определение метода

Метод GetVolume() класса ExampleCube1 возвращает объем куба. Он определяет тип выходных данных в виде числа с плавающей точкой и возвращает результат умножения свойств Height, Length и Width экземпляра .

class ExampleCube1 {
    [float]   $Height
    [float]   $Length
    [float]   $Width

    [float] GetVolume() { return $this.Height * $this.Length * $this.Width }
}

$box = [ExampleCube1]@{
    Height = 2
    Length = 2
    Width  = 3
}

$box.GetVolume()
12

Пример 2. Метод с параметрами

Метод GeWeight() принимает входные данные числа с плавающей точкой для плотности куба и возвращает вес куба, вычисляемый как объем, умноженный на плотность.

class ExampleCube2 {
    [float]   $Height
    [float]   $Length
    [float]   $Width

    [float] GetVolume() { return $this.Height * $this.Length * $this.Width }
    [float] GetWeight([float]$Density) {
        return $this.GetVolume() * $Density
    }
}

$cube = [ExampleCube2]@{
    Height = 2
    Length = 2
    Width  = 3
}

$cube.GetWeight(2.5)
30

Пример 3. Метод без выходных данных

В этом примере определяется Validate() метод с типом выходных данных System.Void. Этот метод не возвращает выходные данные. Вместо этого, если проверка завершается ошибкой, возникает ошибка. Метод GetVolume() вызывает Validate() перед вычислением объема куба. Если проверка завершается неудачно, метод завершается перед вычислением.

class ExampleCube3 {
    [float]   $Height
    [float]   $Length
    [float]   $Width

    [float] GetVolume() {
        $this.Validate()

        return $this.Height * $this.Length * $this.Width
    }

    [void] Validate() {
        $InvalidProperties = @()
        foreach ($Property in @('Height', 'Length', 'Width')) {
            if ($this.$Property -le 0) {
                $InvalidProperties += $Property
            }
        }

        if ($InvalidProperties.Count -gt 0) {
            $Message = @(
                'Invalid cube properties'
                "('$($InvalidProperties -join "', '")'):"
                "Cube dimensions must all be positive numbers."
            ) -join ' '
            throw $Message
        }
    }
}

$Cube = [ExampleCube3]@{ Length = 1 ; Width = -1 }
$Cube

$Cube.GetVolume()
Height Length Width
------ ------ -----
  0.00   1.00 -1.00

Exception:
Line |
  20 |              throw $Message
     |              ~~~~~~~~~~~~~~
     | Invalid cube properties ('Height', 'Width'): Cube dimensions must
     | all be positive numbers.

Метод создает исключение, так как свойства Height и Width недопустимы, что не позволяет классу вычислить текущий том.

Пример 4. Статический метод с перегрузками

Класс ExampleCube4 определяет статический метод GetVolume() с двумя перегрузками. Первая перегрузка имеет параметры для измерений куба и флаг, указывающий, должен ли метод проверять входные данные.

Вторая перегрузка включает только числовые входные данные. Он вызывает первую перегрузку с как $Static$true. Вторая перегрузка дает пользователям возможность вызова метода без необходимости всегда определять, следует ли строго проверять входные данные.

Класс также определяет как GetVolume() экземпляр (нестатический) метод. Этот метод вызывает вторую статическую перегрузку, гарантируя, что метод экземпляра GetVolume() всегда проверяет измерения куба перед возвратом выходного значения.

class ExampleCube4 {
    [float]   $Height
    [float]   $Length
    [float]   $Width

    static [float] GetVolume(
        [float]$Height,
        [float]$Length,
        [float]$Width,
        [boolean]$Strict
    ) {
        $Signature = "[ExampleCube4]::GetVolume({0}, {1}, {2}, {3})"
        $Signature = $Signature -f $Height, $Length, $Width, $Strict
        Write-Verbose "Called $Signature"

        if ($Strict) {
            [ValidateScript({$_ -gt 0 })]$Height = $Height
            [ValidateScript({$_ -gt 0 })]$Length = $Length
            [ValidateScript({$_ -gt 0 })]$Width  = $Width
        }

        return $Height * $Length * $Width
    }

    static [float] GetVolume([float]$Height, [float]$Length, [float]$Width) {
        $Signature = "[ExampleCube4]::GetVolume($Height, $Length, $Width)"
        Write-Verbose "Called $Signature"

        return [ExampleCube4]::GetVolume($Height, $Length, $Width, $true)
    }

    [float] GetVolume() {
        Write-Verbose "Called `$this.GetVolume()"
        return [ExampleCube4]::GetVolume(
            $this.Height,
            $this.Length,
            $this.Width
        )
    }
}

$VerbosePreference = 'Continue'
$Cube = [ExampleCube4]@{ Height = 2 ; Length = 2 }
$Cube.GetVolume()
VERBOSE: Called $this.GetVolume()
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, True)

MetadataError:
Line |
  19 |              [ValidateScript({$_ -gt 0 })]$Width  = $Width
     |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The variable cannot be validated because the value 0 is not a valid
     | value for the Width variable.

Подробные сообщения в определениях методов показывают, как начальный вызов вызывает $this.GetVolume() статический метод.

Вызов статического метода напрямую с параметром Strict как $false возвращает значение 0 для тома.

[ExampleCube4]::GetVolume($Cube.Height, $Cube.Length, $Cube.Width, $false)
VERBOSE: Called [ExampleCube4]::GetVolume(2, 2, 0, False)
0

Сигнатуры и перегрузки методов

Каждый метод класса имеет уникальную сигнатуру, которая определяет способ вызова метода. Тип выходных данных, имя и параметры метода определяют сигнатуру метода.

Если класс определяет несколько методов с одинаковыми именами, определения этого метода являются перегрузками. Перегрузки для метода должны иметь разные параметры. Метод не может определить две реализации с одинаковыми параметрами, даже если выходные типы отличаются.

Следующий класс определяет два метода: Shuffle() и Deal(). Метод Deal() определяет две перегрузки: одну без параметров, а другую — с параметром Count .

class CardDeck {
    [string[]]$Cards  = @()
    hidden [string[]]$Dealt  = @()
    hidden [string[]]$Suits  = @('Clubs', 'Diamonds', 'Hearts', 'Spades')
    hidden [string[]]$Values = 2..10 + @('Jack', 'Queen', 'King', 'Ace')

    CardDeck() {
        foreach($Suit in $this.Suits) {
            foreach($Value in $this.Values) {
                $this.Cards += "$Value of $Suit"
            }
        }
        $this.Shuffle()
    }

    [void] Shuffle() {
        $this.Cards = $this.Cards + $this.Dealt | Where-Object -FilterScript {
             -not [string]::IsNullOrEmpty($_)
        } | Get-Random -Count $this.Cards.Count
    }

    [string] Deal() {
        if ($this.Cards.Count -eq 0) { throw "There are no cards left." }

        $Card        = $this.Cards[0]
        $this.Cards  = $this.Cards[1..$this.Cards.Count]
        $this.Dealt += $Card

        return $Card
    }

    [string[]] Deal([int]$Count) {
        if ($Count -gt $this.Cards.Count) {
            throw "There are only $($this.Cards.Count) cards left."
        } elseif ($Count -lt 1) {
            throw "You must deal at least 1 card."
        }

        return (1..$Count | ForEach-Object { $this.Deal() })
    }
}

Выходные данные метода

По умолчанию методы не имеют выходных данных. Если сигнатура метода включает явный тип выходных данных, отличный от Void, метод должен возвращать объект этого типа. Методы не выдают никаких выходных данных, за исключением случаев, return когда ключевое слово явно возвращает объект .

Параметры методов

Методы класса могут определять входные параметры для использования в теле метода. Параметры метода заключаются в скобки и разделяются запятыми. Пустые скобки указывают, что параметры методу не требуются.

Параметры можно определить в одной или нескольких строках. В следующих блоках показан синтаксис параметров метода.

([[<parameter-type>]]$<parameter-name>[, [[<parameter-type>]]$<parameter-name>])
(
    [[<parameter-type>]]$<parameter-name>[,
    [[<parameter-type>]]$<parameter-name>]
)

Параметры метода могут быть строго типизированы. Если параметр не типизированный, метод принимает любой объект для этого параметра. Если параметр типизированный, метод пытается преобразовать значение этого параметра в правильный тип, вызывая исключение, если входные данные не могут быть преобразованы.

Параметры метода не могут определять значения по умолчанию. Все параметры метода являются обязательными.

Параметры метода не могут иметь других атрибутов. Это не позволяет методам использовать параметры с атрибутами Validate* . Дополнительные сведения об атрибутах проверки см. в разделе about_Functions_Advanced_Parameters.

Для добавления проверки в параметры метода можно использовать один из следующих шаблонов:

  1. Переназначьте параметры тем же переменным с необходимыми атрибутами проверки. Это работает как для статических методов, так и для методов экземпляра. Пример этого шаблона см. в примере 4.
  2. Используйте для Update-TypeData определения объекта , использующего ScriptMethod атрибуты проверки для параметров напрямую. Это работает только для методов экземпляра. Дополнительные сведения см. в разделе Определение методов экземпляра с помощью Update-TypeData .

Автоматические переменные в методах

Не все автоматические переменные доступны в методах. В следующем списке приведены автоматические переменные и предложения по их использованию в методах класса PowerShell. Автоматические переменные, не включенные в список, недоступны для методов класса.

  • $_ — Доступ в обычном режиме.
  • $args — Вместо этого используйте явные переменные параметров.
  • $ConsoleFileName — Доступ $Script:ConsoleFileName как.
  • $Error — Доступ в обычном режиме.
  • $EnabledExperimentalFeatures — Доступ $Script:EnabledExperimentalFeatures как.
  • $Event — Доступ в обычном режиме.
  • $EventArgs — Доступ в обычном режиме.
  • $EventSubscriber — Доступ в обычном режиме.
  • $ExecutionContext — Доступ $Script:ExecutionContext как.
  • $false — Доступ в обычном режиме.
  • $foreach — Доступ в обычном режиме.
  • $HOME — Доступ $Script:HOME как.
  • $Host — Доступ $Script:Host как.
  • $input — Вместо этого используйте явные переменные параметров.
  • $IsCoreCLR — Доступ $Script:IsCoreCLR как.
  • $IsLinux — Доступ $Script:IsLinux как.
  • $IsMacOS — Доступ $Script:IsMacOS как.
  • $IsWindows — Доступ $Script:IsWindows как.
  • $LASTEXITCODE — Доступ в обычном режиме.
  • $Matches — Доступ в обычном режиме.
  • $MyInvocation — Доступ в обычном режиме.
  • $NestedPromptLevel — Доступ в обычном режиме.
  • $null — Доступ в обычном режиме.
  • $PID — Доступ $Script:PID как.
  • $PROFILE — Доступ $Script:PROFILE как.
  • $PSBoundParameters — не используйте эту переменную. Он предназначен для командлетов и функций. Использование его в классе может привести к непредвиденным побочным эффектам.
  • $PSCmdlet — не используйте эту переменную. Он предназначен для командлетов и функций. Использование его в классе может привести к непредвиденным побочным эффектам.
  • $PSCommandPath — Доступ в обычном режиме.
  • $PSCulture — Доступ $Script:PSCulture как.
  • $PSEdition — Доступ $Script:PSEdition как.
  • $PSHOME — Доступ $Script:PSHOME как.
  • $PSItem — Доступ в обычном режиме.
  • $PSScriptRoot — Доступ в обычном режиме.
  • $PSSenderInfo — Доступ $Script:PSSenderInfo как.
  • $PSUICulture — Доступ $Script:PSUICulture как.
  • $PSVersionTable — Доступ $Script:PSVersionTable как.
  • $PWD — Доступ в обычном режиме.
  • $Sender — Доступ в обычном режиме.
  • $ShellId — Доступ $Script:ShellId как.
  • $StackTrace — Доступ в обычном режиме.
  • $switch — Доступ в обычном режиме.
  • $this — Доступ в обычном режиме. В методе $this класса всегда является текущим экземпляром класса . С его помощью можно получить доступ к свойствам и методам класса. Он недоступен в статических методах.
  • $true — Доступ в обычном режиме.

Дополнительные сведения об автоматических переменных см. в разделе about_Automatic_Variables.

Скрытые методы

Методы класса можно скрыть, объявив их с hidden помощью ключевое слово. Скрытые методы класса:

  • Не включен в список членов класса, возвращаемых командлетом Get-Member . Чтобы отобразить скрытые методы с Get-Memberпомощью , используйте параметр Force .
  • Не отображается в завершении табуляции или IntelliSense, если только завершение не происходит в классе, определяющем скрытый метод.
  • Открытые члены класса . Они могут вызываться и наследоваться. Скрытие метода не делает его закрытым. Он только скрывает метод, как описано в предыдущих пунктах.

Примечание

При скрытии перегрузки для метода этот метод удаляется из IntelliSense, результаты завершения и выходные данные по умолчанию для Get-Member.

Дополнительные сведения о hidden ключевое слово см. в разделе about_Hidden.

Статические методы

Метод можно определить как принадлежащий самому классу, а не экземплярам класса, объявив метод с static ключевое слово. Методы статического класса:

  • Всегда доступны, независимо от создания экземпляра класса.
  • Являются общими для всех экземпляров класса .
  • Всегда доступны.
  • Не удается получить доступ к свойствам экземпляра класса . Они могут получить доступ только к статическим свойствам.
  • В режиме реального времени для всего диапазона сеанса.

Методы производного класса

Когда класс является производным от базового класса, он наследует методы базового класса и их перегрузки. Все перегрузки методов, определенные в базовом классе, включая скрытые методы, доступны в производном классе.

Производный класс может переопределить перегрузку наследуемого метода, переопределив ее в определении класса. Чтобы переопределить перегрузку, типы параметров должны быть теми же, что и для базового класса. Тип выходных данных для перегрузки может отличаться.

В отличие от конструкторов, методы не могут использовать : base(<parameters>) синтаксис для вызова перегрузки базового класса для метода . Переопределенная перегрузка в производном классе полностью заменяет перегрузку, определенную базовым классом.

В следующем примере показано поведение статических методов и методов экземпляра в производных классах.

Базовый класс определяет:

  • Статические методы Now() для возврата текущего времени и DaysAgo() для возврата даты в прошлом.
  • Свойство экземпляра TimeStamp и метод экземпляра ToString() , который возвращает строковое представление этого свойства. Это гарантирует, что при использовании экземпляра в строке он преобразуется в строку datetime вместо имени класса.
  • Метод SetTimeStamp() экземпляра с двумя перегрузками. Если метод вызывается без параметров, он задает текущее время в параметре TimeStamp . При вызове метода с параметром DateTime он устанавливает для timestamp это значение.
class BaseClass {
    static [datetime] Now() {
        return Get-Date
    }
    static [datetime] DaysAgo([int]$Count) {
        return [BaseClass]::Now().AddDays(-$Count)
    }

    [datetime] $TimeStamp = [BaseClass]::Now()

    [string] ToString() {
        return $this.TimeStamp.ToString()
    }

    [void] SetTimeStamp([datetime]$TimeStamp) {
        $this.TimeStamp = $TimeStamp
    }
    [void] SetTimeStamp() {
        $this.TimeStamp = [BaseClass]::Now()
    }
}

В следующем блоке определяются классы, производные от BaseClass:

  • DerivedClassA наследуется от BaseClass без каких-либо переопределений.
  • DerivedClassB переопределяет статический DaysAgo() метод для возврата строкового представления вместо объекта DateTime . Он также переопределяет метод экземпляра ToString() для возврата метки времени в виде строки даты ISO8601.
  • DerivedClassC переопределяет перегрузку SetTimeStamp() метода без параметров, чтобы установка метки времени без параметров устанавливала дату на 10 дней раньше текущей даты.
class DerivedClassA : BaseClass     {}
class DerivedClassB : BaseClass     {
    static [string] DaysAgo([int]$Count) {
        return [BaseClass]::DaysAgo($Count).ToString('yyyy-MM-dd')
    }
    [string] ToString() {
        return $this.TimeStamp.ToString('yyyy-MM-dd')
    }
}
class DerivedClassC : BaseClass {
    [void] SetTimeStamp() {
        $this.SetTimeStamp([BaseClass]::Now().AddDays(-10))
    }
}

В следующем блоке показаны выходные данные статического Now() метода для определенных классов. Выходные данные одинаковы для каждого класса, так как производные классы не переопределяют реализацию базового класса метода .

"[BaseClass]::Now()     => $([BaseClass]::Now())"
"[DerivedClassA]::Now() => $([DerivedClassA]::Now())"
"[DerivedClassB]::Now() => $([DerivedClassB]::Now())"
"[DerivedClassC]::Now() => $([DerivedClassC]::Now())"
[BaseClass]::Now()     => 11/06/2023 09:41:23
[DerivedClassA]::Now() => 11/06/2023 09:41:23
[DerivedClassB]::Now() => 11/06/2023 09:41:23
[DerivedClassC]::Now() => 11/06/2023 09:41:23

Следующий блок вызывает статический DaysAgo() метод каждого класса. Только выходные данные для DerivedClassB отличаются, так как они переопределили базовую реализацию.

"[BaseClass]::DaysAgo(3)     => $([BaseClass]::DaysAgo(3))"
"[DerivedClassA]::DaysAgo(3) => $([DerivedClassA]::DaysAgo(3))"
"[DerivedClassB]::DaysAgo(3) => $([DerivedClassB]::DaysAgo(3))"
"[DerivedClassC]::DaysAgo(3) => $([DerivedClassC]::DaysAgo(3))"
[BaseClass]::DaysAgo(3)     => 11/03/2023 09:41:38
[DerivedClassA]::DaysAgo(3) => 11/03/2023 09:41:38
[DerivedClassB]::DaysAgo(3) => 2023-11-03
[DerivedClassC]::DaysAgo(3) => 11/03/2023 09:41:38

В следующем блоке показано представление строки нового экземпляра для каждого класса. Представление для DerivedClassB отличается, так как оно переопределено методом экземпляра ToString() .

"`$base = [BaseClass]::New()     => $($base = [BaseClass]::New(); $base)"
"`$a    = [DerivedClassA]::New() => $($a = [DerivedClassA]::New(); $a)"
"`$b    = [DerivedClassB]::New() => $($b = [DerivedClassB]::New(); $b)"
"`$c    = [DerivedClassC]::New() => $($c = [DerivedClassC]::New(); $c)"
$base = [BaseClass]::New()     => 11/6/2023 9:44:57 AM
$a    = [DerivedClassA]::New() => 11/6/2023 9:44:57 AM
$b    = [DerivedClassB]::New() => 2023-11-06
$c    = [DerivedClassC]::New() => 11/6/2023 9:44:57 AM

Следующий блок вызывает метод экземпляра SetTimeStamp() для каждого экземпляра, устанавливая для свойства TimeStamp определенную дату. Каждый экземпляр имеет одинаковую дату, так как ни один из производных классов не переопределяет параметризованную перегрузку для метода .

[datetime]$Stamp = '2024-10-31'
"`$base.SetTimeStamp(`$Stamp) => $($base.SetTimeStamp($Stamp) ; $base)"
"`$a.SetTimeStamp(`$Stamp)    => $($a.SetTimeStamp($Stamp); $a)"
"`$b.SetTimeStamp(`$Stamp)    => $($b.SetTimeStamp($Stamp); $b)"
"`$c.SetTimeStamp(`$Stamp)    => $($c.SetTimeStamp($Stamp); $c)"
$base.SetTimeStamp($Stamp) => 10/31/2024 12:00:00 AM
$a.SetTimeStamp($Stamp)    => 10/31/2024 12:00:00 AM
$b.SetTimeStamp($Stamp)    => 2024-10-31
$c.SetTimeStamp($Stamp)    => 10/31/2024 12:00:00 AM

Последний блок вызывает SetTimeStamp() без параметров. Выходные данные показывают, что для экземпляра DerivedClassC задано значение на 10 дней раньше остальных.

"`$base.SetTimeStamp() => $($base.SetTimeStamp() ; $base)"
"`$a.SetTimeStamp()    => $($a.SetTimeStamp(); $a)"
"`$b.SetTimeStamp()    => $($b.SetTimeStamp(); $b)"
"`$c.SetTimeStamp()    => $($c.SetTimeStamp(); $c)"
$base.SetTimeStamp() => 11/6/2023 9:53:58 AM
$a.SetTimeStamp()    => 11/6/2023 9:53:58 AM
$b.SetTimeStamp()    => 2023-11-06
$c.SetTimeStamp()    => 10/27/2023 9:53:58 AM

Определение методов экземпляра с помощью Update-TypeData

Помимо объявления методов непосредственно в определении класса, можно определить методы для экземпляров класса в статическом конструкторе с помощью командлета Update-TypeData .

Используйте этот фрагмент в качестве отправной точки для шаблона. При необходимости замените замещающий текст в угловых скобках.

class <ClassName> {
    static [hashtable[]] $MemberDefinitions = @(
        @{
            MemberName = '<MethodName>'
            MemberType = 'ScriptMethod'
            Value      = {
              param(<method-parameters>)

              <method-body>
            }
        }
    )

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

Совет

Командлет Add-Member может добавлять свойства и методы в класс в нестатических конструкторах, но командлет выполняется при каждом вызове конструктора. Использование Update-TypeData в статическом конструкторе гарантирует, что код для добавления членов в класс должен выполняться только один раз в сеансе.

Определение методов со значениями параметров по умолчанию и атрибутами проверки

Методы, определенные непосредственно в объявлении класса, не могут определять значения по умолчанию или атрибуты проверки для параметров метода. Чтобы определить методы класса со значениями по умолчанию или атрибутами проверки, они должны быть определены как члены ScriptMethod .

В этом примере класс CardDeck определяет Draw() метод, который использует атрибут проверки и значение по умолчанию для параметра Count .

class CookieJar {
    [int] $Cookies = 12

    static [hashtable[]] $MemberDefinitions = @(
        @{
            MemberName = 'Eat'
            MemberType = 'ScriptMethod'
            Value      = {
                param(
                    [ValidateScript({ $_ -ge 1 -and $_ -le $this.Cookies })]
                    [int] $Count = 1
                )

                $this.Cookies -= $Count
                if ($Count -eq 1) {
                    "You ate 1 cookie. There are $($this.Cookies) left."
                } else {
                    "You ate $Count cookies. There are $($this.Cookies) left."
                }
            }
        }
    )

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

$Jar = [CookieJar]::new()
$Jar.Eat(1)
$Jar.Eat()
$Jar.Eat(20)
$Jar.Eat(6)
You ate 1 cookie. There are 11 left.

You ate 1 cookie. There are 10 left.

MethodInvocationException:
Line |
  36 |  $Jar.Eat(20)
     |  ~~~~~~~~~~~~
     | Exception calling "Eat" with "1" argument(s): "The attribute
     | cannot be added because variable Count with value 20 would no
     | longer be valid."

You ate 6 cookies. There are 4 left.

Примечание

Хотя этот шаблон работает для атрибутов проверки, обратите внимание, что исключение вводит в заблуждение, ссылаясь на невозможность добавления атрибута. Возможно, лучше явно проверка значение параметра и вызвать значимую ошибку. Таким образом, пользователи могут понять, почему они видят ошибку и что с ней делать.

Ограничения

Методы класса PowerShell имеют следующие ограничения.

  • Параметры метода не могут использовать атрибуты, включая атрибуты проверки.

    Обходной путь. Переназначьте параметры в теле метода с помощью атрибута проверки или определите метод в статическом конструкторе с помощью командлета Update-TypeData .

  • Параметры метода не могут определять значения по умолчанию. Параметры всегда являются обязательными.

    Обходной путь. Определите метод в статическом конструкторе с помощью командлета Update-TypeData .

  • Методы всегда являются общедоступными, даже если они скрыты. Их можно переопределить, когда класс наследуется.

    Обходных решений: нет.

  • Если какая-либо перегрузка метода скрыта, то каждая перегрузка для этого метода тоже считается скрытой.

    Обходных решений: нет.

См. также раздел