как привести значение строки к ее правильному типу - PullRequest
0 голосов
/ 03 марта 2020

У меня есть функция foo, которую я хочу передать Argumentlist в следующем формате:

foo -ArgumentList "a=1", "b=hello", "c=15.00"

Мне нужно знать, является ли значение после каждого = int, string или double (float).

Вот мой код:

Function foo {

    Param(
        [ValidateScript({ $_ -match ".*=.*" })]    
        [string[]]$ArgumentList
    )

    foreach ($Par in $ArgumentList) {

        $Split = $Par -split "="
        $ParamName = $Split[0]
        $ParamValue = $Split[1]

        if ($ParamValue -is [string]) {
            "2049" + $ParamName + $ParamValue
        } 
        elseif ($ParamValue -is [int]) {
            "2050" + $ParamName + $ParamValue
        } 
        elseif ($ParamValue -is [double]) {
            "2051" + $ParamName + $ParamValue
        } 
        else {
            Write-Host "Not a string, int or float."
        }
    } 
}

Однако значение всегда является строкой, что имеет смысл, поскольку оно читается из строки.

Можно ли как-нибудь привести его к правильному типу?

Я знаю, что мог бы сделать что-то подобное, однако это ненадежно, поскольку, например, 1 может быть всем

PS C:\Users\s> "1" -as [int]
1
PS C:\Users\s> "1" -as [double]
1
PS C:\Users\s> "1" -as [string]
1

Ответы [ 4 ]

1 голос
/ 03 марта 2020

Я бы просто использовал метод TryParse(string,[ref]var) типа значения.

Function foo {

    Param(
        [ValidateScript({ $_ -match ".*=.*" })]    
        [string[]]$ArgumentList
    )

    foreach ($Par in $ArgumentList) {

        $temp = $null
        $Split = $Par -split "="
        $ParamName = $Split[0]
        $ParamValue = $Split[1]

        if ([int]::TryParse($ParamValue,[ref]$temp)) {
            $ParamValue = $temp
            "2049" + $ParamName + $ParamValue
            $ParamValue.GetType().FullName
        } 
        elseif ([double]::TryParse($ParamValue,[ref]$temp)) {
            $ParamValue = $temp
            "2050" + $ParamName + $ParamValue
            $ParamValue.GetType().FullName
        } 
        elseif ($ParamValue -is [string]) {
            "2051" + $ParamName + $ParamValue
            $ParamValue.GetType().FullName
        } 
        else {
            Write-Host "Not a string, int or float."
        }
    } 
}

Я добавил $ParamValue.GetType().FullName, чтобы вы могли видеть, какой тип установлен. Метод [type]::TryParse(string,[ref]$temp) попытается привести строку к типу. Он вернет True или False и сохранит соответствующее значение в $temp. False даст 0 значение в $temp в наших тестах. Если True, $temp будет содержать приведенное значение.

Примечание: Вы должны понимать, что, как только вы введете конкатенацию строк ("2048" + somevalue), вывод этого выражения string.

0 голосов
/ 03 марта 2020

Я просто добавил несколько операторов if с приведением типов в вашу функцию.

Function foo {

    Param(
        [ValidateScript({ $_ -match ".*=.*" })]    
        [string[]]$ArgumentList
    )

    foreach ($Par in $ArgumentList) {

        $Split = $Par -split "="
        $ParamName = $Split[0]
        $ParamValue = $Split[1]

        if($ParamName -eq "a"){
            $ParamValue = [int]$ParamValue
        }

        if($ParamName -eq "b"){
            $ParamValue = [string]$ParamValue
        }

        if($ParamName -eq "c"){
            $ParamValue = [double]$ParamValue
        }



        if ($ParamValue -is [string]) {
            "2049" + $ParamName + $ParamValue
        } 
        elseif ($ParamValue -is [int]) {
            "2050" + $ParamName + $ParamValue
        } 
        elseif ($ParamValue -is [double]) {
            "2051" + $ParamName + $ParamValue
        } 
        else {
            Write-Host "Not a string, int or float."
        }
    } 
}
0 голосов
/ 03 марта 2020

Как вы признали, вы устанавливаете тип как строку, когда передаете значение в свой параметр, оно всегда должно оцениваться как строка.

Если вы установите свой параметр как массив, ваша функция может работать. В приведенном ниже примере Get-Member показывает типы объектов в массиве.

Как вы получаете значение для вашего параметра? Возможно, лучше изменить формат, прежде чем передать его в свою функцию.

[string]$a= "string"
[int]$b = 1
[array]$array = $a,$b
$array | Get-Member
0 голосов
/ 03 марта 2020

Вы можете протестировать ограниченные типы, используя -as, как это -

$val = '23.00' #input value to be type-casted

$intVal = $val -as [int]
$floatVal = $val -as [float]

if ($null -ne $floatVal -and $intVal -ne $floatVal) {
$val = $floatVal # value is float type
} elseif ($null -ne $intVal) {
$val = $intVal # value is int type
} else {
Write-output '$val is already string type' # value is not float or int, so use it as string
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...