Powershell自定义类创建问题

问题描述 投票:0回答:1

当我开始使用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呢?

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

任何信息,解释或教育将非常感谢!

谢谢大家!迈克尔

powershell exception powershell-v5.0 new-object
1个回答
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()澄清我的脚本实际上被赋予了一组对象。

© www.soinside.com 2019 - 2024. All rights reserved.