Function overloading in PowerShell

Для меня это было потому, что у изображений был «.png» в инспекторе атрибутов. Удаление этого исправило проблему

29
задан Peter Mortensen 15 July 2015 в 17:58
поделиться

3 ответа

В PowerShell функции не перегружены. Последнее определение переопределяет предыдущее в той же области или скрывает предыдущее в родительской области. Таким образом, вы должны создать одну функцию и предоставить способ различать режим ее вызова по аргументам.

В V2 вы можете использовать расширенную функцию, см. help about_Functions_Advanced_Parameters и избегать ручного кодирования для разрешения неоднозначностей набора параметров:

# advanced function with 3 parameter sets
function Backup-UsersData
(
    [Parameter(Position=0, ParameterSetName="user")]
    [string]$user,
    [Parameter(Position=0, ParameterSetName="array")]
    [object[]]$array,
    [Parameter(Position=0, ParameterSetName="all")]
    [switch]$all
)
{
    # use this to get the parameter set name
    $PSCmdlet.ParameterSetName
}

# test
Backup-UsersData -user 'John'
Backup-UsersData 1, 2
Backup-UsersData -all

# OUTPUT:
# user
# array
# all

Обратите внимание, что этот механизм иногда странный. Например, в первом тесте мы должны явно указать имя параметра -user. В противном случае:

Backup-UsersData : Parameter set cannot be resolved using the specified named parameters.
At C:\TEMP\_101015_110059\try2.ps1:21 char:17
+ Backup-UsersData <<<<  'John'
    + CategoryInfo          : InvalidArgument: (:) [Backup-UsersData], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Backup-UsersData

Во многих случаях стандартная, а не расширенная функция со смешанными параметрами будет выполнять:

function Backup-UsersData
(
    [string]$user,
    [object[]]$array,
    [switch]$all
)
{
    if ($user) {'user'}
    elseif ($array) {'array'}
    elseif ($all) {'all'}
    else {'may be'}
}

Backup-UsersData -user 'John'
Backup-UsersData -array 1, 2
Backup-UsersData -all
Backup-UsersData

Но в этом случае вам следует разрешить (или принять и игнорировать) неясности, например решить, что делать, если, скажем:

Backup-UsersData -user 'John' -array 1, 2 -all
28
ответ дан 28 November 2019 в 01:54
поделиться

Вот вариант ответа Романа, который я считаю более гибким:

function Backup
{
    [CmdletBinding(DefaultParameterSetName='Users')]
    Param (
        [parameter(mandatory=$true, ParameterSetName='Users', position=0, ValueFromPipeline=$true)][string[]]$User,
        [parameter(mandatory=$true, ParameterSetName='AllUsers')][switch]$All
    )

    Begin
    {
        if ($All) { $User = @('User1', 'User2', 'User3') }
    }

    Process
    {
        foreach ($u in $User)
        {
            echo "Backup $u"
        }
    }
}
6
ответ дан 28 November 2019 в 01:54
поделиться

При использовании PSObject вместо Объекта определить тип параметра он должен работать. Например, функциональное Получать-управление, know's, как перегрузиться на основе строки типа или обработать по шаблону и может быть назван с помощью данных позиционирования:

    Get-Control "A-Name-Of-A-Control"
    Get-Control $template

, Чтобы заставить перегрузку работать, используйте PSObject следующим образом:

Function Get-Control {
    Param(
        [Parameter(Mandatory=$False,ParameterSetName="ByTemplate",Position=0)]
        [PSObject]
        $Template,

        [Parameter(Mandatory=$False,ParameterSetName="ByName",Position=0)]        
        [String]
        $Name,

        [Parameter(Mandatory=$False)] 
        [Switch]
        $List
      ) 
   ... # remaining code removed for brevity
1
ответ дан 28 November 2019 в 01:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: