0

当我开始使用 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]$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"."

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

谢谢大家!迈克尔

4

1 回答 1

0

我认为问题源于[node]在当前的 powershell 会话中有类型的对象,然后重新定义[node]类型。似乎有[node]基于文件内容的不同定义。

[node].guid使用查看类的不同定义可能有助于使这一点更清晰。

这是一个演示该问题的简单再现:

类1.ps1:

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

测试类a.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
异常设置“next”:“无法将“A”类型的“A”值转换为“A”类型。”  
在 /home/veefu/src/throwaway/testclassa.ps1:13 char:1
+ $aobj1.next = $aobj2
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+fullyQualifiedErrorId : ExceptionWhenSetting

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

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

于 2018-08-31T09:24:24.587 回答