Сделайте PowerShell, чтобы объект не перечислил

Я работал над некоторыми функциями PowerShell для управления объектами, реализованными в сборке, которую мы создали. Один из классов, с которыми я работал с инструментами IEnumerable. К сожалению, это заставляет PowerShell разворачивать объект при каждой возможности. (Я не могу изменить тот факт, что класс реализует IEnumerable.)

Я работал над проблемой, создав PSObject и скопировав свойства нашего пользовательского объекта в PSObject, а затем вернул это вместо пользовательского объекта. Но я бы скорее вернул наш пользовательский объект.

Есть ли какой-то способ, предположительно, используя мой файл types.ps1xml, чтобы скрыть метод GetEnumerator() этого класса от PowerShell (или иначе сказать PowerShell никогда не разворачивать его).

Ответ 1

Обход в PSObject - лучший способ.

Вы также можете явно обернуть его в другой коллекции. PowerShell только разворачивает один уровень.

Также при написании командлета в С#/VB/... при вызове WriteObject используйте перегрузку, которая принимает второй параметр: если false, то PowerShell не будет перечислять объект, переданный в качестве первого параметра.

Ответ 2

Проверьте замену Write-Output http://poshcode.org/2300, у которой есть параметр -AsCollection, который позволяет избежать разворачивания. Но в основном, если вы пишете функцию, которая выводит коллекцию, и вы не хотите, чтобы эта коллекция была развернута, вам нужно использовать CmdletBinding и PSCmdlet:

function Get-Array {
    [CmdletBinding()]
    Param([Switch]$AsCollection) 

    [String[]]$data = "one","two","three","four"
    if($AsCollection) {
        $PSCmdlet.WriteObject($data,$false)
    } else {
        Write-Output $data
    }
}

Если вы вызовете это с помощью -AsCollection, вы получите совсем другие результаты, хотя они будут ПОСМОТРЕТЬ ЖЕ САМОЙ в консоли.

C:\PS> Get-Array 

one
two
three
four

C:\PS> Get-Array -AsCollection

one
two
three
four

C:\PS> Get-Array -AsCollection| % { $_.GetType() }


IsPublic IsSerial Name       BaseType                             
-------- -------- ----       --------                             
True     True     String[]   System.Array                         



C:\PS> Get-Array | % { $_.GetType() }


IsPublic IsSerial Name       BaseType                             
-------- -------- ----       --------                             
True     True     String     System.Object                        
True     True     String     System.Object                        
True     True     String     System.Object                        
True     True     String     System.Object