Ключ Hashtable с точкой - PullRequest
2 голосов
/ 15 февраля 2020

Как мне выдать табличный ключ ha sh с точечным символом, таким как FlatAppearance.BorderSize, чтобы он был правильным?

$Button = [System.Windows.Forms.Button] @{

    # This is not a valid entry
    FlatAppearance.BorderSize = 0
}
$Button = [System.Windows.Forms.Button] @{

    # This is not a valid entry too
    "FlatAppearance.BorderSize" = 0
}
$Button = [System.Windows.Forms.Button] @{

    # This is not a valid entry too too
    FlatAppearance = @{ BorderSize = 0 }
}

Конечно, я можно написать так

$Button = [System.Windows.Forms.Button] @{}
$Button.FlatAppearance.BorderSize = 0

Однако удобнее писать в таблице ha sh. Но как? Спасибо

1 Ответ

1 голос
/ 15 февраля 2020

Поскольку свойство .FlatAppearance типа Button относится к типу FlatButtonAppearance, в этом случае хорошего решения не существует, поскольку тип FlatButtonAppearance имеет no publi c, без параметров конструктор .

Если это так, вы сможете написать:

using namespace System.Windows.Forms

$Button = [Button] @{

    # !! This is how you would generally do it, but
    # !! IN THIS CASE IT DOESN'T WORK, due to lack of an appropriate constructor.
    FlatAppearance = [FlatButtonAppearance] @{ BorderSize = 0 }
}

Синтаксис вышеупомянутый похож на C# синтаксис инициализатора объекта , объясненный в следующем разделе.


Синтаксис инициализатора объекта в PowerShell:

Для приведения к введите литерал ([...]) из хеш-таблицы (@{ ... }) или , существовавший ранее [pscustomobject] экземпляр [1] для выполнения неявного построения ( неявное создание экземпляра), а затем инициализация нескольких свойств для работы необходимо выполнить следующие предварительные условия :

  • Целевой тип должен иметь конструктор (возможно, среди прочих [2] ):

    • publi c
    • и занимает нет р arameters [3]
  • Имена типа publi c свойств должны соответствовать элементам хеш-таблицы ключи и значения записей должны иметь тот же или совместимый тип, что и свойства назначения.

Это позволяет PowerShell создавать экземпляр за сценой, просто вызывая new SomeType() ([SomeType]::new() в синтаксисе PowerShell) с последующим назначением значений свойств * publi c из записей с хеш-таблицами с одинаковыми именами.


Помимо обращения к документации по типу, вы можете легко проверить конструкторы типа в PowerShell путем вызова предоставляемого PowerShell метода * stai c ::new без скобок (()):

PS> [System.Windows.Forms.FlatButtonAppearance]::new
# NO OUTPUT, which means the type has no public constructors at all.

# [ProcessStartInfo] has several public constructors, among them
# a public parameterless one, so you *can* initialize it by hashtable.
PS> [System.Diagnostics.ProcessStartInfo]::new

OverloadDefinitions
-------------------
System.Diagnostics.ProcessStartInfo new()
System.Diagnostics.ProcessStartInfo new(string fileName)
System.Diagnostics.ProcessStartInfo new(string fileName, string arguments)

К определить публикуемые c типа, доступные для записи свойства экземпляра :

PS> [System.Windows.Forms.FlatButtonAppearance].GetProperties('Public, Instance') | 
       ? CanWrite | Select-Object Name, PropertyType

Name               PropertyType        
----               ------------        
BorderSize         System.Int32        
BorderColor        System.Drawing.Color
CheckedBackColor   System.Drawing.Color
MouseDownBackColor System.Drawing.Color
MouseOverBackColor System.Drawing.Color

[1] Например, это полезно для десериализованных объектов из JSON, которые становятся [pscustomobject] случаи; например: $obj = '{ "Text": "Submit" }' | ConvertFrom-Json; $button = [Button] $obj

[2] Пограничный регистр: не должно быть также одиночного -параметра publi c с одним из следующих параметров типы, потому что он будет связывать приведенный операнд как есть:
* [object] или
* при приведении из хеш-таблицы (@{ ... }): [hashtable] или [System.Collections.IDictionary]
* при приведении из экземпляра [pscustomobject]: [psobject] или [pscustomobject]

[3] Удобно, если вы определяете тип (класс) без объявления any конструктор, вы получаете c без параметров по умолчанию ; Например, в следующем примере PowerShell класс Foo неявно предоставляет такой конструктор:
class Foo { [string] $Bar }; $foo = [Foo] @{ Bar = 'None' }

...