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


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 возвращает том куба. Он определяет тип вывода как число с плавающей запятой и возвращает результат умножения свойств высоты, длины и ширины экземпляра.

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, используйте параметр Force .
  • Не отображается в завершении вкладки или IntelliSense, если только не выполняется завершение в классе, определяющем скрытый метод.
  • Открытые члены класса. Их можно вызывать и наследовать. Скрытие метода не делает его частным. Он скрывает метод, как описано в предыдущих точках.

Примечание.

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

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

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

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

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

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

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

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

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

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

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

  • Статические методы Now() для возврата текущего времени и DaysAgo() возврата даты в прошлом.
  • Свойство instance TimeStamp и метод экземпляраToString(), возвращающий строковое представление этого свойства. Это гарантирует, что при использовании экземпляра в строке она преобразуется в строку datetime вместо имени класса.
  • Метод SetTimeStamp() экземпляра с двумя перегрузками. При вызове метода без параметров задается метка времени в текущее время. При вызове метода с помощью 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:

  • Производный классA наследует от BaseClass без переопределения.
  • Производный КлассB переопределяет статический DaysAgo() метод, чтобы возвращать строковое представление вместо объекта DateTime . Он также переопределяет метод экземпляра ToString() , чтобы вернуть метку времени в виде строки даты ISO8601.
  • Производный КлассC переопределяет перегрузку без параметров метода, чтобы задать метку 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 .

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

    Обходной путь: нет.

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

    Обходной путь: нет.

См. также