一次设置多个属性 - 相当于 VB 的 With 语句来提供隐含的对象上下文

问题描述 投票:0回答:3

仅供学习。

假设我有一个变量,在本例中是一个文本框,如何一次设置多个属性而无需一遍又一遍地输入变量名称。

我自己尝试过一些东西,其中一个由于某种奇怪的原因而起作用。

这个例子有效。 Break 用于缩短循环。

 $Textbox | % {
    $_.Text = "Hello World"
    $_.Background = "Black"
    $_.Foreground = "Green"
    Break
 }

这两个示例不起作用,在这里只是为了看看我尝试过什么。

这有或没有“$_.”,而不是“.”。我用过“=”和“+=”,但都不起作用。

 $Textbox.@{
    Text = "Hello World"
    Background = "Black"
    Foreground = "Green"
 }

 $Textbox.({
    $_.Text = "Hello World"
    $_.Background = "Black"
    $_.Foreground = "Green"
 })

可能有更简单的方法,我在谷歌上没有找到任何东西。

powershell syntax
3个回答
7
投票

您正在寻找的是一种语言构造,例如 VB[Script] 的 With

 语句
,它允许您在内部为“无对象”属性引用(例如 .Text
)设置隐含上下文一个块。

PowerShell 中

没有这样的构造

您的第一次尝试是 PowerShell 中最接近的模拟,尽管以牺牲性能为代价(尽管这可能并不重要):在管道中,自动变量$_

允许对输入对象进行简洁引用手。

重要不要在管道内使用break

:它不仅会退出管道,还会退出任何封闭的
循环,以及在没有循环的情况下退出封闭脚本使用 return 代替。

也就是说,在当前的情况下,只有一个

单个

输入对象,不需要return


至于
你的其他尝试

    语法
  • @{...}

    仅用于

    哈希表文字
    。尝试使用此语法作为属性名称会导致语法错误。

  • 语法
  • (...)

    计算所包含的任何单个命令/表达式;

    {...}
    定义了一个
    脚本块

      实际上并未
    • 执行

      的脚本块(需要&),当在

      字符串上下文
      中使用时 - 例如此处的属性名称,计算出其在 { 和 之间的文字内容
      }
      ,即一个多行字符串,显然
      not
      代表$TextBox的现有属性的名称,因此总体结果是
      $null
      
      

    • 请注意,在适当的
    • 严格模式

      下运行的脚本 - 使用 Set-StrictMode -Version 2 或更高模式 - 会将上述尝试

      访问
      不存在的属性标记为错误 相比之下,尝试分配
      到不存在的属性总是会生成错误。

但是请注意,
PowerShell 在

构造对象的上下文中提供了方便的多属性初始化,在 PowerShell 中,您通常也可以通过hashtable初始化器使用casts来实现。 # Cast a hashtable with property name/value pairs to # [System.Windows.Forms.TextBox], which implicitly constructs # an instance with the specified property values: $TextBox = [System.Windows.Forms.TextBox] @{ Text = "Hello World" Location = [Point]::new(10, 50) }

需要注意的是,
此技术的可用性取决于目标类型是否具有

无参数构造函数 - 有关详细信息,请参阅此答案


1
投票

function Set-Properties( [parameter(ValueFromPipeline)] $inputObject, [hashtable] $properties, [switch] $passThru ) { process { Add-Member -InputObject $inputObject -NotePropertyMembers $properties -force if ([bool]$passThru) { $inputObject } } }

用途:

Set-Properties $Textbox @{ Text = "Hello World" Background = "Black" Foreground = "Green" }



$Textbox1, $Textbox2 | Set-Properties -properties @{ Text = "Hello World" Background = "Black" Foreground = "Green" } -passThru | ForEach { # do something }



0
投票

即使类没有无参数构造函数,也可以通过使用 -ArgumentList [Object[]] 和 -Property [IDictionary] 的组合来初始化对象。

Class TestClass { [string]$ConstructorProperty [string]$PublicProperty [string]$PublicProperty1 # ... # Note: a constructor is defined. TestClass([string]$ConstructorProperty) { $this.ConstructorProperty = $ConstructorProperty } } New-Object TestClass ` -ArgumentList @('c0') ` -Property @{ PublicProperty = 'p0'; PublicProperty1 = 'p1'}

© www.soinside.com 2019 - 2024. All rights reserved.