Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Краткое описание
Описание определения свойств для классов PowerShell.
Длинное описание
Свойства являются членами класса, содержащего данные. Свойства объявляются как переменные в области класса. Свойство может быть любого встроенного типа или экземпляра другого класса. Классы могут нулю или больше свойств. Классы не имеют максимального количества свойств.
Свойства класса могут иметь любое количество атрибутов, включая скрытые и статические атрибуты. Каждое определение свойства должно содержать тип для свойства. Можно определить значение по умолчанию для свойства.
Синтаксис
Свойства класса используют следующие синтаксисы:
Однострочный синтаксис
[[<attribute>]...] [<property-type>] $<property-name> [= <default-value>]
Синтаксис с несколькими линиями
[[<attribute>]...]
[<property-type>]
$<property-name> [= <default-value>]
Примеры
Пример 1. Минимальные свойства класса
Свойства класса ExampleProject1 используют встроенные типы без атрибутов или значений по умолчанию.
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
Значение по умолчанию для свойств Name и Assignee является $null, так как они вводимы в виде строк, которые являются ссылочным типом. Другие свойства имеют значение по умолчанию для определенного типа, так как они имеют свойства типа значений. Дополнительные сведения о значениях по умолчанию для свойств см. в значения свойств по умолчанию.
Пример 2. Свойства класса с пользовательскими типами
Свойства ExampleProject2 включают пользовательское перечисление и класс, определенный в PowerShell перед классом 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
Пример 3. Свойство класса с атрибутом проверки
Класс ExampleProject3 определяет свойство Size как целое число, которое должно быть больше или равно 0 и меньше или равно 16. Он использует атрибут ValidateRange для ограничения значения.
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
Если ExampleProject3 создается экземпляр, Размер по умолчанию — 0. При задании свойства значение в допустимом диапазоне обновляется.
$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
Если размер имеет недопустимое значение за пределами диапазона, PowerShell вызывает исключение, а значение не изменяется.
$project.Size = 32
$project.Size = -1
$project
SetValueInvocationException:
Line |
1 | $project.Size = 32
| ~~~~~~~~~~~~~~~~~~
| 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."
SetValueInvocationException:
Line |
2 | $project.Size = -1
| ~~~~~~~~~~~~~~~~~~
| 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."
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
Пример 4. Свойство класса с явным значением по умолчанию
Класс ExampleProject4 по умолчанию использует значение свойства startDate для текущей даты.
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
Пример 5. Скрытое свойство класса
Свойство guid Guid класса ExampleProject 5 имеет ключевое слово hidden. Свойство guid guid не отображается в выходных данных по умолчанию для класса или в списке свойств, возвращаемых 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;}
Пример 6. Свойство статического класса
Класс ExampleProject6 определяет свойство статических Projects как список всех созданных проектов. Конструктор по умолчанию для класса добавляет новый экземпляр в список проектов.
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
Пример 7. Определение свойства в конструкторе
Класс ExampleProject7 определяет свойство скрипта Duration в конструкторе статических классов с помощью командлета Update-TypeData. Использование командлета Update-TypeData или Add-Member является единственным способом определения расширенных свойств для классов PowerShell.
Свойство длительности возвращает значение $null, если только свойства startDate startDate и EndDate заданы и StartDate определяются как более ранние, чем 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
Представление по умолчанию для экземпляра класса ExampleProject7 включает длительность. Так как свойства и EndDate StartDate не заданы, свойство 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
При правильном настройке свойств свойство Duration возвращает интервал времени, представляющий время выполнения проекта.
Значения свойств по умолчанию
Каждое свойство класса имеет неявное значение по умолчанию в зависимости от типа свойства.
Если свойство является ссылочным типом, например строкой или объектом, неявное значение по умолчанию $null. Если свойство является типом значения , например числом, логическим или перечислением, свойство имеет значение по умолчанию в зависимости от типа:
- Числовые типы, такие как целые числа и числа с плавающей запятой, по умолчанию
0 - Логические значения по умолчанию
$false - Перечисления по умолчанию
0, даже перечисление не определяет метку для0.
Дополнительные сведения о значениях по умолчанию в .NET см. в значения по умолчанию типов C# (справочник по C#).
Чтобы определить явное значение по умолчанию для свойства, объявите свойство с назначением значению по умолчанию.
Например, это определение для класса ProjectTask определяет явное значение по умолчанию для свойства guid Guid, назначая случайный GUID каждому новому экземпляру.
class ProjectTask {
[string] $Name
[string] $Description
[string] $Guid = (New-Guid).Guid
}
[ProjectTask]::new()
Name Description Guid
---- ----------- ----
aa96350c-358d-465c-96d1-a49949219eec
Скрытые и статические свойства также могут иметь значения по умолчанию.
Скрытые свойства
Свойства класса можно скрыть, объявив их с помощью ключевого слова hidden.
Скрытые свойства класса:
- Не включен в выходные данные по умолчанию для класса.
- Не включен в список членов класса, возвращаемых командлетом
Get-Member. Чтобы отобразить скрытые свойства сGet-Member, используйте параметр Force. - Не отображается в завершении вкладки или IntelliSense, если только не выполняется завершение в классе, определяющем скрытое свойство.
- Открытые члены класса. К ней можно обращаться и изменять. Скрытие свойства не делает его частным. Он скрывает только свойство, как описано в предыдущих точках.
Дополнительные сведения о ключевом слове hidden см. в about_Hidden.
Статические свойства
Свойство можно определить как принадлежащее самому классу вместо экземпляров класса, объявив свойство с ключевым словом static. Свойства статического класса:
- Всегда доступны независимо от экземпляра класса.
- Общий доступ ко всем экземплярам класса.
- Всегда доступны.
- Модификаторы. Статические свойства можно обновить. По умолчанию они неизменяемы.
- Динамическая трансляция для всего диапазона сеансов.
Важный
Статические свойства для классов, определенных в PowerShell, не являются неизменяемыми. Их можно переопределить на любое допустимое значение, как определено типом и атрибутами статического свойства.
Свойства производного класса
Если класс является производным от базового класса, он наследует свойства базового класса. Все свойства, определенные в базовом классе, включая скрытые свойства, доступны в производном классе.
Производный класс может переопределить унаследованное свойство, переопределив его в определении класса. Свойство в производном классе использует переопределенный тип и значение по умолчанию, если таковые имеются. Если унаследованное свойство определило значение по умолчанию и переопределенное свойство не имеет, унаследованное свойство не имеет значения по умолчанию.
Если производный класс не переопределяет статическое свойство, доступ к статическому свойству через производный класс обращается к статическому свойству базового класса. Изменение значения свойства через производный класс изменяет значение базового класса. Любой другой производный класс, который не переопределяет статическое свойство, также использует значение свойства в базовом классе. Обновление значения унаследованного статического свойства в классе, который не переопределяет свойство, может иметь непредвиденные последствия для классов, производных от одного базового класса.
В следующем примере показано поведение свойств статического и экземпляра в производных классах.
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 для DerivedClassC является пустой строкой, так как класс переопределен свойству без задания значения по умолчанию. Для DerivedClassD значение Override, так как класс переопределен свойству в качестве значения по умолчанию.
"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
За исключением Производного класса, значение статического свойства для производных классов совпадает с базовым классом, так как они не переопределяют свойство. Это относится даже к Производный КлассC, который наследуется от Производный КлассB, а не непосредственно от 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
Когда staticProperty обращается и изменяется с помощью DerivedClassA, измененное значение влияет на каждый класс, за исключением DerivedClassD.
Дополнительные сведения о наследовании классов, включая полный пример, см. в about_Classes_Inheritance.
Использование атрибутов свойств
PowerShell включает несколько классов атрибутов, которые можно использовать для улучшения сведений о типе данных и проверки данных, назначенных свойству. Атрибуты проверки позволяют проверить, что значения, заданные свойствам, соответствуют определенным требованиям. Проверка активируется момент назначения значения.
Дополнительные сведения о доступных атрибутах см. в about_Functions_Advanced_Parameters.
Определение свойств экземпляра с помощью Update-TypeData
Помимо объявления свойств непосредственно в определении класса, можно определить свойства для экземпляров класса в статическом конструкторе с помощью командлета Update-TypeData.
Используйте этот фрагмент в качестве отправной точки для шаблона. Замените текст заполнителя в угловых скобках по мере необходимости.
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
}
}
}
Кончик
Командлет Add-Member может добавлять свойства и методы в класс в нестатических конструкторах, но командлет выполняется каждый раз при вызове конструктора. Использование Update-TypeData в статическом конструкторе гарантирует, что код для добавления членов в класс должен выполняться только один раз в сеансе.
Только добавляйте свойства в класс в нестатических конструкторах, если они не могут быть определены с помощью Update-TypeData, например свойств только для чтения.
Определение свойств псевдонима
Атрибут Alias не влияет на использование в объявлении свойств класса. PowerShell использует только этот атрибут для определения псевдонимов для имен командлетов, параметров и функций.
Чтобы определить псевдоним для свойства класса, используйте Update-TypeData с AliasPropertyMemberType.
Например, это определение класса OperablePair определяет два целочисленных свойства x и y с псевдонимами LeftHandSide и 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 }
}
Определяя псевдонимы, пользователи могут получить доступ к свойствам с помощью любого имени.
$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
Определение вычисляемых свойств
Чтобы определить свойство, ссылающееся на значения других свойств, используйте командлет Update-TypeData с ScriptPropertyMemberType.
Например, это определение класса Бюджет определяет свойства Expenses и Revenues в виде массивов чисел с плавающей запятой. Он использует командлет Update-TypeData для определения вычисляемых свойств для общих расходов, общего дохода и чистого дохода.
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}
Определение свойств с помощью пользовательской логики получения и задания
Свойства класса PowerShell не могут определять пользовательскую логику получения и задания напрямую. Вы можете приблизить эту функцию, определив резервное свойство с ключевым словом hidden и используя Update-TypeData для определения видимого свойства с пользовательской логикой для получения и задания значения.
По соглашению определите скрытое имя свойства резервного копирования с префиксом подчеркивания и используйте регистр верблюда. Например, вместо TaskCountприсвойте имя скрытому свойству резервного копирования _taskCount.
В этом примере класс ProjectSize определяет скрытое целочисленное свойство с именем _value. Он определяет значение как ScriptProperty с пользовательской логикой для получения и настройки свойства _value. Блок скрипта setter обрабатывает преобразование строкового представления проекта в правильный размер.
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
}
}
Определяя настраиваемый метод получения и задания, можно задать свойство Value как целое число или строку.
$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
Ограничения
Свойства класса PowerShell имеют следующие ограничения:
Статические свойства всегда изменяются. Классы PowerShell не могут определять неизменяемые статические свойства.
Обходное решение: нет.
Свойства не могут использовать атрибут ValidateScript, так как аргументы атрибута свойства класса должны быть константами.
Обходное решение. Определите класс, наследующий от типа ValidateArgumentsAttribute, и используйте этот атрибут.
Непосредственно объявленные свойства не могут определять пользовательские реализации получения и задания.
Обходное решение. Определите скрытое свойство и используйте
Update-TypeDataдля определения видимой логики получения и задания.Свойства не могут использовать атрибут Alias. Атрибут применяется только к параметрам, командлетам и функциям.
Обходное решение. Используйте командлет
Update-TypeDataдля определения псевдонимов в конструкторах классов.При преобразовании класса PowerShell в JSON с помощью командлета
ConvertTo-Jsonвыходные данные JSON включают все скрытые свойства и их значения.Обходное решение: Нет
См. также
PowerShell