从实际变量获取powershell变量名

Rob*_*ere 4 variables powershell readonly pass-by-reference variable-names

我试图弄清楚如何从对象本身获取 powershell 变量的名称。

我这样做是因为我正在对通过引用传递到函数中的对象进行更改,因此我不知道该对象是什么,并且我正在使用 Set-Variable cmdlet 将该变量更改为只读。

# .__NEEDTOGETVARNAMEASSTRING is a placeholder because I don't know how to do that.

function Set-ToReadOnly{
  param([ref]$inputVar)
  $varName = $inputVar.__NEEDTOGETVARNAMEASSTRING
  Set-Variable -Name $varName -Option ReadOnly
}
$testVar = 'foo'
Set-ToReadOnly $testVar
Run Code Online (Sandbox Code Playgroud)

我浏览了很多类似的问题,但找不到任何具体答案。我想完全在函数内部使用变量——我不想依赖于传递附加信息。

另外,虽然可能有更简单/更好的设置只读的方法,但我长期以来一直想知道如何可靠地从变量中提取变量名称,所以请专注于解决该问题,而不是我在其中的应用这个例子。

mkl*_*nt0 6

Mathias R. Jessen 的有用答案解释了为什么如果仅传递原始变量的就无法可靠地确定原始变量。

解决您的问题的唯一可靠的解决方案是传递变量对象而不是其值作为参数

function Set-ToReadOnly {
  param([psvariable] $inputVar) # note the parameter type
  $inputVar.Options += 'ReadOnly'
}

$testVar = 'foo'
Set-ToReadOnly (Get-Variable testVar) # pass the variable *object*
Run Code Online (Sandbox Code Playgroud)

如果您的函数是在与调用代码相同的范围内定义的 -如果您的函数是在(不同的)模块中定义的,则情况并非如此- 您可以更简单地仅传递变量名称并从父级/祖先中检索变量范围:

# Works ONLY when called from the SAME SCOPE / MODULE
function Set-ToReadOnly {
  param([string] $inputVarName)
  # Retrieve the variable object via Get-Variable.
  # This will implicitly look up the chain of ancestral scopes until
  # a variable by that name is found.
  $inputVar = Get-Variable $inputVarName
  $inputVar.Options += 'ReadOnly'
}

$testVar = 'foo'
Set-ToReadOnly testVar # pass the variable *name*
Run Code Online (Sandbox Code Playgroud)