Может ли функция Powershell обрабатывать несколько типов ввода?

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

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 ответ

Решение

Как утверждает Jeff Zeitlin в своем комментарии:

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

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

Эта способность определять применимый набор параметров аналогична автоматическому разрешению перегрузки в 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
Другие вопросы по тегам