Can';似乎没有将泛型集合与PowerShell类一起使用

Can';似乎没有将泛型集合与PowerShell类一起使用,powershell,Powershell,我试图调用直接向初始列表添加一个项的方法,就像这样,其中T是我编写的PowerShell类(下面的示例使用类名Thing: $someObject=Get Thing#返回单个对象 $list=[list[Thing]]::新建(@($someObject)) 但是,这会产生一个错误,提示它找不到此构造函数的重载: 找不到“List`1”和参数计数“1”的重载 将List[T]设置为对象类有效,但是: $someObject=Get Thing $list=[list[Object]]::新建

我试图调用直接向初始
列表添加一个项的方法,就像这样,其中
T
是我编写的PowerShell类(下面的示例使用类名
Thing

$someObject=Get Thing#返回单个对象
$list=[list[Thing]]::新建(@($someObject))
但是,这会产生一个错误,提示它找不到此构造函数的重载:

找不到“List`1”和参数计数“1”的重载

List[T]
设置为
对象
类有效,但是:

$someObject=Get Thing
$list=[list[Object]]::新建(@($someObject))
虽然这样做有效,但我不确定为什么我不能使用PowerShell类作为类型。我的理解是,它们不能与泛型一起使用,但以下说明我的类不是
ContextBoundObject

类的东西{
$Name
物品($name){
$this.Name=$Name
}
}
$thing=[thing]::新建('Bender')
$thing-是[System.ContextBoundObject]#==>False
我不确定PowerShell类是否是某种嵌套类型,也没有提到嵌套类型

我不确定为什么无法使用PowerShell类作为类型

数组子表达式操作符
@()
将其结果返回为
[object[]]
——一种满足参数类型
[IEnumerable[object]]
——这就是为什么在使用
[object]
作为接收集合类型的类型参数时,它总是起作用的原因


那么,该怎么办呢

如果数组仅由
[Thing]
组成,则可以显式强制转换为实现
[IEnumerable[Thing]]
的更具体的集合类型:

$list = [List[Thing]]::new([Thing[]]@( $someObject ))
我不确定为什么无法使用PowerShell类作为类型

数组子表达式操作符
@()
将其结果返回为
[object[]]
——一种满足参数类型
[IEnumerable[object]]
——这就是为什么在使用
[object]
作为接收集合类型的类型参数时,它总是起作用的原因


那么,该怎么办呢

如果数组仅由
[Thing]
组成,则可以显式强制转换为实现
[IEnumerable[Thing]]
的更具体的集合类型:

$list = [List[Thing]]::new([Thing[]]@( $someObject ))
作为补充,它很好地解释了问题并提供了有效的解决方案:

PowerShell的强制转换不仅在语法上更方便,而且在按需类型转换方面也更灵活

实际上,使用强制转换而不是通过静态的
::new()
方法调用构造函数确实有效

using namespace System.Collections.Generic

class Thing { [string] $Name; Thing([string] $name) { $this.Name = $name } }

# Both of the following work:

# Single [Thing] instance.
$list = [List[Thing]] [Thing]::new('one')

# Multiple [Thing] instances, as an array, via the grouping operator, (...)
# @(...), the array subexpression operator, works too, but is unnecessary.
$list = [List[Thing]] ([Thing]::new('one'), [Thing]::new('two'))

PowerShell的自动类型转换,也用于强制转换: 遗憾的是,在撰写本文时,这些规则还没有形成文档,但提供了一个高层次的概述,可以按优先级降序总结如下:

  • 首先,可以应用引擎内部的固定转换规则(参见链接)

    • 一个值得注意的内部规则涉及到到字符串的转换:尽管任何.NET类型都通过显式调用其
      .ToString()
      方法(从对象层次结构的根继承而来,
      System.object
      ),但PowerShell应用自定义规则:

      • 如果类型具有区域性敏感的
        .ToString()
        重载,PowerShell会故意传递不变区域性,以实现区域性不变表示,而直接
        .ToString()则
        调用将产生区域性敏感表示法-有关详细信息,请参阅;例如,在
        是小数点的区域性中,
        [string]1.2
        返回
        '1.2'
        (句点),而
        (1.2).ToString()
        返回
        '1,2'
        (逗号)

      • 集合,包括数组,通过将它们的(字符串化的)元素与一个空格作为分隔符连接起来进行字符串化(默认情况下,可以用首选变量
        $OFS
        覆盖);例如,
        [string](1,2)
        返回
        12
        ,而
        (1,2).ToString()
        仅返回
        System.Object[]

  • 接下来,将考虑实现特定类型的自定义转换的或()类

  • 如果输入类型是字符串(
    [string]
    ),则认为是静态的
    ::Parse()
    方法,如果存在:首先是具有区域性敏感签名的方法,
    ::Parse(,)
    ,在这种情况下传递不变区域性,否则是具有签名的方法

  • 接下来,如果输入类型与参数的类型匹配或可转换为该类型,则考虑使用单参数构造函数

  • 如果存在用于输入和目标类型之间转换的隐式或显式

  • 最后,如果输入对象实现了接口,并且目标类型是除
    [IntPtr]
    [UIntPtr]
    或以下类型之一之外的受实现支持的类型:
    [datetime]
    [DBNull]
    [decimal]

作为补充,它很好地解释了问题并提供了有效的解决方案:

PowerShell的强制转换不仅在语法上更方便,而且在按需类型转换方面也更灵活

实际上,使用强制转换而不是通过静态的
::new()
方法调用构造函数确实有效

using namespace System.Collections.Generic

class Thing { [string] $Name; Thing([string] $name) { $this.Name = $name } }

# Both of the following work:

# Single [Thing] instance.
$list = [List[Thing]] [Thing]::new('one')

# Multiple [Thing] instances, as an array, via the grouping operator, (...)
# @(...), the array subexpression operator, works too, but is unnecessary.
$list = [List[Thing]] ([Thing]::new('one'), [Thing]::new('two'))

PowerShell的自动类型转换,也用于强制转换: 不幸的是,在撰写本文时,这些规则还没有被记录下来,但在描述中提供了一个高层次的概述,可以总结如下