Powershell - Как использовать $ List.convertAll () или альтернативный метод C # для клонирования списка - PullRequest
0 голосов
/ 01 июня 2018

Предположим, у меня есть список:

$DeletedUsers = New-Object System.Collections.Generic.List[System.object]

Так что я могу легко добавлять и удалять пользователей из коллекции.

Я хочу передать этот список функции, которая выполняетчто-то, но без изменения исходного списка, и он должен остаться того же общего типа списка.

convertAll(), кажется, делает именно то, что я хочу, без необходимости самостоятельно создавать сценарий создания нового списка с помощью foreach-object, но я не понимаю, как использовать определения перегрузки (или совершенно не понимаю, что они означают).

Есть много примеров в C #, но я не смог найти тот, который демонстрирует этов PoSH.

Пример сценария:

Предположим, что $ DeletedUsers содержит список объектов User типа PSCustomObject.С типичными свойствами пользователя, такими как отдел или статус занятости.Этот список должен передаваться функциям, которые будут изменять статусы свойства users, которые затем могут быть добавлены в отдельный выходной список того же типа Generic.List.

В настоящее время любые изменения в примере функции.

    Function ProcessUser {

    [Cmdletbinding()]
    Param($DeletedUsers)

    begin{$DeletedUsersClone = $($DeletedUsers).psobject.copy()} #OR similar

    process{
    $DeletedUsersClone | foreach { $_ | Add-Member -NotePropertyName 
    "Processed" -NotePropertyValue "Processed:00"; $Outputlist.add($_)} 
           }
                         }

Влияет на исходный $ DeletedUsers, ошибочно добавляя обработанную информацию в список, который должен оставаться статичным.

Существуют альтернативные способы предотвращения влияния этого на конечную цель сценария,но вопрос в следующем:

Как создать True, не имеющий ссылки клон System.Collections.Generic.List [System.object], используя встроенные методы C #.

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Примечание:

  • Как выяснилось позже, OP ищет клон deep исходного списка;т. е. не только список в целом должен быть клонирован, но и его элементы .

  • Этот ответ показывает только, как создать мелкий клон (и как передать список только для чтения).

    • См. полезный ответ Брюса Пайетта для глубины - клонирование на основе метода .ConvertAll [pscustomobject] экземплярами вы должны использовать следующее (но учтите, что .psobject.Copy() создает только полных копий самих [pscustomobject] экземпляров):

      $DeletedUsers.ConvertAll([converter[pscustomobject, pscustomobject]] {param ($obj) $obj.psobject.copy() })
      

  • Если вы хотите передать мелкий клон вашего списка вызываемому абоненту:

    • Pass [Collections.Generic.List[object]]::new($DeletedUsers) (PSv5 + синтаксис)
    • В качестве альтернативы, если тип элементов списка неизвестен или вы не хотите его повторять, передайте: $DeletedUsers.GetRange(0, $DeletedUsers.Count)
  • Если вы просто хотите предотвратить случайное изменение вашего списка вызываемым абонентом:

    • Pass $DeletedUsers.AsReadOnly() - однако, делает изменить тип, а именно на [Collections.ObjectModel.ReadOnlyCollection[object]]
0 голосов
/ 01 июня 2018

Хитрость заключается в том, чтобы использовать скрипт-блок с явным приведением к типу делегата.Это выглядит так:

$DeletedUsers.ConvertAll([converter[object,object]] {param ($i) <# do convert #> })
...