Como impedir que um argumento de seqüência de caracteres mude de nulo para vazio quando vinculado a um parâmetro?
Considere o seguinte código:
function f {
param (
[AllowNull()]
[string]
$x
)
return $x
}
$r = f -x $null
$null
é convertido para[string]::Empty
quando chegar a horareturn
é atingido.$null
é diferente de[string]::Empty
e eu gostaria de preservar essa distinção. Eu também preferiria manter$x
como tipo[string]
Porque$x
só tem significado como uma string e a interface é usada em outro lugar.
$x
sair como$null
quando é passado$null
?Existe alguma outra maneira de dizer isso$x
passou$null
não [string]::Empty
de dentrof
?Atualização 1
O que estou tentando fazer funciona para outros tipos. Aqui está o mesmo conceito para[int]
:
function f {
param(
[System.Nullable[int]]$x
)
return $x
}
$r = f -x $null
Nesse caso$r
é de fato$null
. $x
pode ser$null
ou[int]
mas nada mais. Parece-me estranho ter que permitirqualquer objeto apenas para que eu possa passar um$null
ou[int]
.
[System.Nullable[string]]
produz um erro que se resume a[System.Nullable[T]]
requer que[T]
é um tipo de valor.[string]
é um tipo de referência, para que não funcione.
Atualização 2
Parece ser possível passar$null
sem causar a conversão para um parâmetro de qualquer tipoexceto [string]
. Eu testei o seguinte:
function f { param([System.Nullable[int]]$x) $x }
function f { param([System.Nullable[System.DayOfWeek]]$x) $x }
function f { param([hashtable]$x) $x }
function f { param([array]$x) $x }
function f { param([System.Collections.Generic.Dictionary[string,int]]$x) $x }
function f { param([System.Collections.ArrayList]$x) $x }
function f { param([System.Collections.BitArray]$x) $x }
function f { param([System.Collections.SortedList]$x) $x }
function f { param([System.Collections.Queue]$x) $x }
function f { param([System.Collections.Stack]$x) $x }
Passagem$null
para qualquer uma dessas funções gera $ null. osó tipo de parâmetro Eu não encontrei uma maneira de passar$null
sem conversão é[string]
.
Atualização 3
O comportamento do PowerShell nesse sentido também é inconsistente com o C #. A função correspondente em C # é a seguinte:
public string f(string x)
{
return x;
}
Chamandof(null)
retornanull
.
Atualização 4
Pelo visto[NullString]::Value
foi planejado para resolver esse problema. Eu pareço trabalhar para passarnull
parastring
parâmetros em APIs C #. Contudo,[NullString]::Value
é convertido em[string]::empty
no PowerShell, o mesmo que$null
. Considere o seguinte código:
function f {
param (
[AllowNull()]
[string]
$x
)
return $x
}
$r = f -x ([NullString]::Value)
$r.GetType().Name
Executando que o código geraString
. $r
é[string]::Empty
Apesar disso[NullString]::Value
foi passado para$x
.
Atualização 5
A equipe do PowerShell indicou que isso ocorreu por design:
Isso ocorre por design e ... mudar o comportamento seria uma grande mudança de quebra.
Esse tópico envolveu uma discussão interessante sobre o raciocínio por trás dele. Suspeito que algumas ramificações desse comportamento não tenham sido entendidas quando a decisão foi tomada, pois o comportamento contraria diretamenteCmdlet do PowerShell "Diretriz de design fortemente incentivado" SD03 que lê em parte da seguinte maneira:
Se o seu parâmetro precisar diferenciar entre três valores: $ true, $ false e "não especificado", defina um parâmetro do tipo Nullable. A necessidade de um terceiro valor "não especificado" geralmente ocorre quando o cmdlet pode modificar uma propriedade booleana de um objeto. Nesse caso, "não especificado" significa não alterar o valor atual da propriedade.