【发布时间】:2020-07-11 08:10:10
【问题描述】:
我在 PS 5.1 中添加新型加速器时遇到了麻烦。我找到了this,以及其他一些类似的参考资料,所以我的理解是,PowerShell 的所有 5.# 版本都是这种情况,而不仅仅是参考的预览版。为此,我有这个
CLS
$accelerators = [PowerShell].Assembly.GetType("System.Management.Automation.TypeAccelerators")
$accelerators::Add("pxList",[System.Collections.Generic.List[string]])
$accelerators::Add("pxHashList",[System.Collections.Generic.List[hashtable]])
$builtinTypeAccelerators = $accelerators.GetField("builtinTypeAccelerators", [System.Reflection.BindingFlags]"Static,NonPublic")
$builtinTypeAccelerators.SetValue($builtinTypeAccelerators, $accelerators::Get)
class pxT_DefinitionsMigrater {
# Properties
$XML = [xml.xmlDocument]::new()
$Errors = [pxList]::new()
$initiations = [pxHashList]::new()
# Constructor
pxT_DefinitionsMigrater ([string]$xmlPath) {
}
}
[pxT_DefinitionsMigrater]::new('String')
我仍然收到Unable to find type 错误。我哪里错了?有趣的是,这确实有效。
CLS
$accelerators = [PowerShell].Assembly.GetType("System.Management.Automation.TypeAccelerators")
$accelerators::Add("pxList",[System.Collections.Generic.List[string]])
$accelerators::Add("pxHashList",[System.Collections.Generic.List[hashtable]])
$builtinTypeAccelerators = $accelerators.GetField("builtinTypeAccelerators", [System.Reflection.BindingFlags]"Static,NonPublic")
$builtinTypeAccelerators.SetValue($builtinTypeAccelerators, $accelerators::Get)
([pxHashList]::new()).GetType().FullName
似乎自定义类型加速器不适用于类(以相同的方式)。所以也许更重要的是,添加我们自己的类型加速器是否仍然被认为是好的做法,或者自 PS5 以来的这种变化是否表明我们真的不应该这样做?或者至少不与课程结合使用?
另外,顺便说一句,但肯定不值得提出实际问题,我注意到new 方法没有大写。当我在 ISE 中获得我的新类型的智能选项时,Equals 和 ReferenceEquals 都大写,但 new 不是。我见过的每个new 都是如此。似乎其中一定包含了一些有用的信息。
编辑:非常有趣的发现,就在我最初的帖子之后。 这也有效
CLS
$accelerators = [PowerShell].Assembly.GetType("System.Management.Automation.TypeAccelerators")
$accelerators::Add("pxList",[System.Collections.Generic.List[string]])
$accelerators::Add("pxHashList",[System.Collections.Generic.List[hashtable]])
$builtinTypeAccelerators = $accelerators.GetField("builtinTypeAccelerators", [System.Reflection.BindingFlags]"Static,NonPublic")
$builtinTypeAccelerators.SetValue($builtinTypeAccelerators, $accelerators::Get)
class pxT_DefinitionsMigrater {
# Properties
$XML = [xml.xmlDocument]::new()
$Errors = $null
$initiations = $null
# Constructor
pxT_DefinitionsMigrater ([string]$xmlPath) {
$this.Errors = [pxList]::new()
$this.initiations = [pxHashList]::new()
}
}
[pxT_DefinitionsMigrater]::new('String')
因此,可以在属性部分为 XML 属性分配一个实际值,即空 [xml.document],但我无法在那里创建新类型的新空版本,我需要在 ctor 中进行。让我想知道是否有一个参数总是在声明时将属性设置为$null,然后在构造函数中赋值。所以...
CLS
$accelerators = [PowerShell].Assembly.GetType("System.Management.Automation.TypeAccelerators")
$accelerators::Add("pxList",[System.Collections.Generic.List[string]])
$accelerators::Add("pxHashList",[System.Collections.Generic.List[hashtable]])
$builtinTypeAccelerators = $accelerators.GetField("builtinTypeAccelerators", [System.Reflection.BindingFlags]"Static,NonPublic")
$builtinTypeAccelerators.SetValue($builtinTypeAccelerators, $accelerators::Get)
class pxT_DefinitionsMigrater {
# Properties
[xml.xmlDocument]$XML = $null
[pxList]$Errors = $null
[pxHashList]$initiations = $null
# Constructor
pxT_DefinitionsMigrater ([string]$xmlPath) {
$this.XML = [xml.xmlDocument]::new()
$this.Errors = [pxList]::new()
$this.initiations = [pxHashList]::new()
}
}
[pxT_DefinitionsMigrater]::new('String')
如果您有许多 ctor 变体,这似乎有点浪费,但也许是最佳实践?
编辑:确实,似乎是第二次运行才能让事情正常工作,而不是在使用加速器的地方。鉴于这最终将是一个脚本而不是在 ISE 中运行,因此在这两个地方都适用的答案将是理想的。
$accelerators = [PowerShell].Assembly.GetType("System.Management.Automation.TypeAccelerators")
$accelerators::Add("pxList",[System.Collections.Generic.List[string]])
$accelerators::Add("pxHashList",[System.Collections.Generic.List[hashtable]])
$builtinTypeAccelerators = $accelerators.GetField("builtinTypeAccelerators", [System.Reflection.BindingFlags]"Static,NonPublic")
$builtinTypeAccelerators.SetValue($builtinTypeAccelerators, $accelerators::Get)
class pxT_DefinitionsMigrater {
# Properties
[xml.xmlDocument]$XML
[pxList]$Errors
[pxHashList]$initiations
# Constructor
[Void]initializeProperties () {
$this.XML = [xml.xmlDocument]::new()
$this.Errors = [pxList]::new()
$this.initiations = [pxHashList]::new()
}
pxT_DefinitionsMigrater ([string]$xmlPath) {
$this.initializeProperties()
}
}
[pxT_DefinitionsMigrater]::new('String')
【问题讨论】:
-
嗯,另一件事。如果您分两次执行,看起来就像您的第一个示例工作。这意味着如果您选择自定义加速器然后 F8 然后加载剩余的东西(类定义 + 新对象)
标签: powershell type-accelerators