powershell,如何安全地存储变量类型以备将来使用

h7wcgrx3  于 2023-01-13  发布在  Shell
关注(0)|答案(1)|浏览(109)

我从JSON文件中加载了一些配置,我希望能够检查我刚刚加载的内容,并可能设置一些默认值。
现在,我创建了一个包含信息的哈希表,然后以这种方式加载和检查

$config_info=@{
    foo=@{default='' ;type=[string]}
    bar=@{default=@();type=[array] }
}

$config = Get-Content $configPath -Raw | ConvertFrom-Json

if(-not [Bool]$config.PSObject.Properties['foo']) {
    $config | Add-Member -MemberType NoteProperty -Name 'foo' -Value $config_info.foo.default 
}

if($config.foo -isnot $config_info.foo.type) { ... }

但我想知道type=[string]的表示法有多安全,我是否应该使用type=''.getType(),它看起来不太自然。

更新1

在过去,我使用Export-Clixml/Import-Clixml作为我的配置文件,但生成的文件几乎是人类可读/可编辑的。
我有时也使用点源PS1文件,但对于目前的项目,配置必须由非powershell的人维护。
我想知道的是,type=[string]是否是一种安全/持久的语法来将''.getType()存储在变量中。

7hiiyaii

7hiiyaii1#

我想知道的是,type=[string]是一个安全/持久的语法来存储''.getType()在一个变量中,或没有。

  • 是的,假设. NET [string]类型(System.String)没有被同名的自定义class定义所"遮蔽"(这样做是不明智的)。
  • [string]是一个PowerShell type literal,并且引用. NET类型的这种方式是可以预见的,* 假设类型已经加载到会话中 *,对于内置类型(如System.String),这是根据定义成立的。
  • 按其accelerator名称(如果已定义);例如[string][regex];使用.FullName属性查看类型的全名;例如[regex].FullName
  • 按其 * 全名 *,但请注意,您可以随意省略名称空间的System.部分,例如,您可以将System.Text.Encoding称为[System.Text.Encoding][Text.Encoding]
  • 通过其 * 程序集限定名称 *;例如(使用[string].AssemblyQualifiedName获得):
[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]`
  • 然而:
  • 这不适用于PowerShell版本,至少不适用于内置类型。
  • 这几乎是不必要的,而且可能给人一种错误的印象,以为引用的是给定的程序集版本(. NET似乎加载了任何可用的版本)
  • 但是,仅在 . NET(核心)/PowerShell(核心) 中,您可以 * 省略 * Version字段;类似地,CulturePublicKeyToken是可选。
  • 虽然我怀疑是否会出现这种需要,特别是对于内置类型,但至少假设您可以通过其宿主程序集消除具有相同全名的类型的歧义;例如:
# PS Core (v7+) only; the PublicKeyToken field may be omitted.
 [System.String, System.Private.CoreLib, PublicKeyToken=7cec85d7bea7798e]
  • 在PowerShell(Core)7+中,ConvertFrom-Json具有-AsHashtable开关,该开关将解析结果作为 * 哈希表 * 而不是[pscustomobject]示例返回。
  • 假设您可以从哈希表强制转换为自定义的class类型文字,则可以使用强类型属性,其默认值与输入JSON数据中的属性相对应。
# Custom class that describes the structure of the config data,
# with strongly typed properties and default values.
class Config {
   [string] $foo = '(none)'
   [int[]] $bar = @()
}

# Sample JSON input; parse it into a hashtable.
$ht = @'
{
  "bar": [1, 2]
}
'@ | ConvertFrom-Json -AsHashtable

# Construct a [Config] instance from the values in the hashtable,
# enforcing data types, with on-demand conversion.
[Config] $ht

输出(请注意foo的默认值):

foo    bar
---    ---
(none) {1, 2}

注:

  • PowerShell灵活的自动类型转换在构造Config示例时使用,并且考虑到PowerShell允许将 * any * 数据类型转换为[string],因此仍然接受[string]类型属性的非字符串输入(导致字符串化)。
  • 当值的类型错误且无法转换时(例如,[int]类型的属性的值为"abc"),[Config]强制转换将导致语句终止错误。
  • 如果您需要更严格的类型检查,请考虑使用 * JSON schema * 验证,Test-Json通过-Schema-SchemaFile参数支持该验证,仅在PowerShell(核心)中使用,如zett42所建议。

相关问题