Powershell定制类创建问题

时间:2018-08-31 03:16:30

标签: powershell exception powershell-v5.0 new-object

当我逐步使用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.

通过我对使用不正确类型时会发生什么的测试,但不确定为什么我会间歇性地看到这种情况。一个简单的示例,该示例通过传递预期在 Node int 故意重现该错误。 :)

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

以下内容确实使我感到困惑。在 NodeTest.ps1 中添加空白行后, Node 如何不能成为 Node ,然后又神奇地成为 Node

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

任何信息,解释或教育,将不胜感激!

谢谢! 迈克尔

1 个答案:

答案 0 :(得分:0)

我认为问题源于当前Powershell会话中具有类型[node]的对象,然后重新定义了[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
Exception setting "next": "Cannot convert the "A" value of type "A" to type "A"."  
At /home/veefu/src/throwaway/testclassa.ps1:13 char:1
+ $aobj1.next = $aobj2
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting

尽管[A]的实际定义是相同的,但类型系统似乎将[A]的两个版本视为不同的类型,而无需在它们之间进行转换。

如果修修补补是您的学习方式,那么对.gettype()方法和| format-list *表达式的熟悉将为您提供很好的服务。这些有助于洞察PS为您创建的对象的类型和属性。通常应通过检查返回的对象的类型来澄清来自应“正常工作”的代码的不透明错误。我记得很多时候我的脚本期望一个对象并且有一些奇怪的行为或错误,.gettype()澄清了我的脚本实际上是被赋予了对象的集合。