Вопрос создания пользовательского класса 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()
пояснил, что моему сценарию фактически предоставляется коллекция объектов.