Может ли функция Powershell обрабатывать несколько типов ввода? - PullRequest
1 голос
/ 17 октября 2019

Я работаю над функцией, которая сравнивает два объекта, чтобы он обнаруживал их, если они идентичны. Однако я хотел бы, чтобы он также работал с другими типами, такими как строки или целые числа.

C ++ позволяет объявлять разные функции с одним и тем же именем для обработки вызовов функций с разными типами ввода по-разному. Я знаю о существовании наборов параметров, однако, насколько я знаю, именно пользователь должен указать, какой набор параметров он использует.

Я пытаюсь сделать что-то подобное

function Compare-Objects{
    Param(
        [Parameter(Mandatory=$true,
        Position=0,
        ParameterSetName = "Hashtables")]
        [ValidateNotNullOrEmpty()] 
        [Hashtable]$Item1Hash,

        [Parameter(Mandatory=$true,
        Position=0,
        ParameterSetName = "Integers")]
        [ValidateNotNullOrEmpty()] 
        [int]$Item1int,

        [Parameter(Mandatory=$true,
        Position=1,
        ParameterSetName = "Hashtables")]
        [ValidateNotNullOrEmpty()]
        [Hashtable]$Item2Hash,

        [Parameter(Mandatory=$true,
        Position=1,
        ParameterSetName = "Integers")]
        [ValidateNotNullOrEmpty()]
        [Hashtable]$Item2Int
    )
    if($PSCmdlet.ParameterSetNamePositionv -match "Integers"){ Return ($Item1Int -eq $Item2Int)}
    else{
    #do some other stuff with $Item1Hash and $Item2Hash
    }
}

Дополнительные баллы, если я могу также назвать переменные одинаковыми (поэтому $Item1Hash и $Item1Int становятся обоими $Item1 с назначенным подходящим типом)

1 Ответ

1 голос
/ 17 октября 2019

Как Джефф Цейтлин заявляет в своем комментарии:

Пользователям НЕ нужно явно указывать набор параметров - PowerShell выводит применимый набор параметров из конкретной комбинации аргументов (или их отсутствия), переданной при вызове.

Вывод основан на аргументе типы данных , переданы ли аргументы позиционно (не предшествует имени параметра) и какие параметры помечены как обязательный , а имя набора параметров, который вступает в силу, отражено в $PSCmdlet.ParameterSetName внутри (расширенного) сценария / функции invoked.

Эта способность выводить применимый набор параметров аналогичен автоматическому разрешению перегрузки в C-подобных языках.


Хотя любой данный параметр может участвоватьв множественных наборах параметров - и по умолчанию является частью всех из них - , вы принципиально не можете объявить параметры с помощью то же имя , но разные типы данных .

Если вам нужны такие «полиморфные» параметры, вам придется реализовать собственную логику , который не зависит от наборов параметров:

function Compare-Objects {

  [CmdletBinding(PositionalBinding=$false)]
  Param(

      [Parameter(Mandatory, Position=0)]
      [ValidateNotNullOrEmpty()] 
      # Define as [object] to initially accept any value; specific types
      # are later enforced inside the function body.
      [object] $Item1 
      ,
      [Parameter(Mandatory, Position=1)]
      [ValidateNotNullOrEmpty()] 
      [object] $Item2
  )

  # Ensure that a supported type was passed.
  if ($Item1.GetType() -notin [int], [hashtable]) { Throw "Unsupported argument type." }

  # Ensure that both arguments have the same type.
  if ($Item1.GetType() -ne $Item2.GetType()) { Throw "Inconsistent argument types." }

  if ($Item1 -is [int]) {
    "[int] arguments given."
  }
  else {
    "[hashtable] arguments given."
  }

}

Однако , если использовать те же самые имена параметров, не является обязательным требованием, и высодержимое с позиционным вызовом с использованием различных типов данных , наборы параметров могут помочь, как демонстрирует следующий упрощенный пример:

function Foo {
  [CmdletBinding()]
  param(
    [Parameter(ParameterSetName='int', Position=0)]
    [int] $ItemInt
    ,
    [Parameter(ParameterSetName='hash', Position=0)]
    [hashtable] $ItemHash
  )
  "Parameter set chosen: $($PSCmdlet.ParameterSetName)"
 } 

# Call the function first with an [int], then with a [hashtable], positionally.
10, @{ foo = 1 } | ForEach-Object { Foo $_ }

Выше приведено следующее, показывающее, что данные аргументаТип автоматически выбирается соответствующий набор параметров:

Parameter set chosen: int
Parameter set chosen: hash
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...