Вопрос создания пользовательского класса Powershell

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

> PS C:\Users\Purpl_000> C:\PS\Node\NodeTest.ps1 Cannot convert the
> "Node" value of type "Node" to type "Node". At
> C:\PS\Node\NodeTest.ps1:5 char:1
> + [Node]$node1 = New-Object Node -Property @{Next=$null; Value=3};
> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMetadataException
>     + FullyQualifiedErrorId : RuntimeException   Exception setting "Next": "Cannot convert the "Node" value of type "Node" to type
> "Node"." At C:\PS\Node\NodeTest.ps1:9 char:1
> + $node2.Next = $node1;
> + ~~~~~~~~~~~~~~~~~~~~
>     + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
>     + FullyQualifiedErrorId : ExceptionWhenSetting   New-Object : The value supplied is not valid, or the property is read-only. Change the
> value, and then try again. At C:\PS\Node\NodeTest.ps1:13 char:16
> + [Node]$node3 = New-Object Node -Property @{Next=$node2; Value=9};
> +                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     + CategoryInfo          : InvalidData: (:) [New-Object], Exception
>     + FullyQualifiedErrorId : SetValueException,Microsoft.PowerShell.Commands.NewObjectCommand  
> Cannot find an overload for "new" and the argument count: "2". At
> C:\PS\Node\NodeTest.ps1:22 char:1
> + [Node]$node4 = [Node]::new($node3, 12);
> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     + CategoryInfo          : NotSpecified: (:) [], MethodException
>     + FullyQualifiedErrorId : MethodCountCouldNotFindBest

Вот Node.ps1

class Node
{
    [Node]$Next;
    [int]$Value;

    # .ctor
    Node([Node]$next, [int]$value)
    {
        $this.Next = $next;
        $this.Value = $value;
    }

    # default .ctor
    Node() {}


    static [int] Method1([Node]$n1)
    {
        return $n1.Value;
    }

    static [Node] Method2([Node]$n2)
    {
        $n2.Value = $n2.Value + 5;
        return $n2.Value;
    }
}

Вот NodeTest.ps1

. 'C:\PS\Node\Node.ps1';

[Node]$node1 = New-Object Node -Property @{Next=$null; Value=3};
[Node]$node2 = [Node]::new();
$node2.Next = $node1;
$node2.Value = 5;

[Node]$node3 = New-Object Node -Property @{Next=$node2; Value=9};

[Node]$node4 = [Node]::new($node3, 12);

Я работаю в PowerShell ISE. Node.ps1 сохранен и успешно запущен. NodeTest.ps1 также сохраняется, но иногда дует до тех пор, пока я не внесу кажущиеся не относящимися к делу изменения в файл, сохраните и снова запустите скрипт. В этот момент все снова работает нормально. Примеры изменений, которые разрешили проблему: (1) добавление дополнительной строки пробела, (2) удаление дополнительной строки пробела, (3) добавление комментария и т. Д.

я понимаю

New-Object : The value supplied is not valid, or the property is read-only. Change the value, and then try again.

через мое тестирование того, что происходит, когда вы используете неправильные типы, но не совсем уверен, почему я периодически вижу это. Простой пример намеренного повторения этой ошибки, передавая int там, где ожидается Node.:)

[Node]$node3 = New-Object Node -Property @{Next=5; Value=9};

Следование действительно смущает меня. Как узел может не быть узлом, а затем волшебным образом снова стать узлом после добавления пустой строки в NodeTest.ps1?

Exception setting "Next": "Cannot convert the "Node" value of type "Node" to type "Node"."

Любая информация, объяснения или образование будут чрезвычайно признательны!

Спасибо всем! Майкл

1 ответ

Я думаю, что проблема связана с наличием объектов типа [node] в текущем сеансе PowerShell, а затем переопределить [node] тип. Кажется, есть четкие определения [node] на основе содержимого файла.

Что может помочь сделать это немного яснее, используя [node].guid чтобы увидеть четкие определения вашего класса.

Вот простая репродукция, демонстрирующая проблему:

classa1.ps1:

#class A def 1
class A {
    [A] $next
}

testclassa.ps1:

. ./classa1.ps1
$aobj1 = new-object A
Write-Host "Current A definition GUID: $([A].guid)"

" " | out-file  -Append ./classa1.ps1
. ./classa1.ps1
$aobj2 = new-object A
Write-Host "New A definition GUID: $([A].guid)"

# throws conversion exception because the type definition of 
# $aobj1.next now differs from the current [A] definition
$aobj1.next = $aobj2
Параметр исключения "следующий": "Невозможно преобразовать значение" А "типа" А "в тип" А "."  
На /home/veefu/src/throwaway/testclassa.ps1:13 char:1
+ $aobj1.next = $aobj2
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo: NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId: ExceptionWhenSetting

Кажется, система типов относится к двум версиям [A] как отдельные типы без преобразования между ними, несмотря на фактическое определение [A] быть идентичным

Если ваш стиль обучения - мастеринг, знакомство с .gettype() метод и | format-list * Выражение хорошо послужит вам. Они дают представление о типах и свойствах объектов, которые PS создает для вас. Непрозрачные ошибки, исходящие из кода, который должен "просто работать", часто выявляются путем проверки типа возвращаемого объекта. Я часто вспоминаю, что мои сценарии ожидали одного объекта и имели странное поведение или ошибку, где .gettype() пояснил, что моему сценарию фактически предоставляется коллекция объектов.

Другие вопросы по тегам