Powershell 5.#在同一文件中添加类型加速器并在类中使用
我在PS5.1中添加新型加速器时遇到了麻烦。我找到了,以及其他一些类似的参考资料,所以我的理解是,这是所有5个PowerShell版本的情况,而不仅仅是参考预览版。为此,我有这个Powershell 5.#在同一文件中添加类型加速器并在类中使用,powershell,type-accelerators,Powershell,Type Accelerators,我在PS5.1中添加新型加速器时遇到了麻烦。我找到了,以及其他一些类似的参考资料,所以我的理解是,这是所有5个PowerShell版本的情况,而不仅仅是参考预览版。为此,我有这个 CLS $accelerators = [PowerShell].Assembly.GetType("System.Management.Automation.TypeAccelerators") $accelerators::Add("pxList",[System.Colle
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')
我仍然发现找不到类型
错误。我哪里做错了?有趣的是,这确实有效
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
不是。这对于我所看到的每一个新的都是如此。看来这里面一定有一些有用的信息
编辑:非常有趣的发现,就在我第一篇文章之后。
这同样有效
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.document]
的properties部分为XML属性分配一个实际值,但是我不能在那里创建新类型的新空版本,我需要在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')
包含类定义的Powershell代码首先对它们进行求值
#有效!
[myClass]::new()
开始睡眠-3秒
类myClass{}#此行首先运行
#抛出!
这条线先开
函数f{}
f:术语“f”无法识别为cmdlet、函数等的名称。。。
问题是
类pxT\u DefinitionsMigrater
试图使用尚未定义的类型
解决办法是
在单独的文件中定义类型和类
首先加载类型定义文件,然后加载类定义
更新
可以在单个文件中基于
函数GetPxLists{
if(((“pxList”-as[type])-eq$null){
$accelerators=[PowerShell].Assembly.GetType(“System.Management.Automation.TypeAccelerators”)
$accelerators::添加(“pxList”,[System.Collections.Generic.List[string]]
$accelerators::Add(“pxHashList”,[System.Collections.Generic.List[hashtable]]
$BuiltentyPeAccelerators=$accelerators.GetField(“BuiltentyPeAccelerators”、[System.Reflection.BindingFlags]“静态、非公开”)
$BuiltentyPeAccelerators.SetValue($BuiltentyPeAccelerators,$accelerators::Get)
}
[pxList]::new(),[pxHashList]::new()
}
#在课堂上
#建造师
pxT_定义过滤器([string]$xmlPath){
$PxLists=GetPxLists
$this.Errors=$PxLists[0]
$this.initiations=$PxLists[1]
}
Hmmm,还有一件事。如果您在两次内完成,看起来就像您的第一个示例工作。这意味着,如果选择自定义加速器,然后选择F8,然后加载剩余的内容(类定义+新对象),有趣的是,这似乎不可能有一个包含类和类型加速器的自包含模块,这似乎是一件常见的事情。但是,这是微软,所以我想我必须选择课程或加速器,我会选择课程。加速器是一种便利,类解决了污染的管道问题,这本身就值得放弃定制加速器:-)不过,我还是希望微软能做到这一点。我们不应该选择两者中的任何一个。我们找到了一个更好的答案@戈登,你能不能把这个问题说成是“重复的”(没有人标记)?这是一个有趣的问题。快速查看显示该解决方案适用于方法,而我至少尝试在属性默认值中使用自定义类型加速器。但是,关于编译的一点确实帮助我理解了一点。这些类不只是加载,它们必须编译以便使用,然后从第一行开始执行。在任何情况下,现在看看我是否可以将其作为属性的默认值。如果可以的话,我会把它标记为一个副本。在我看来,你不必选择。模块可以非常独立。该模块可以由多个psm1/psd1文件组成。加速器和类可以位于模块中包含的2个附加数据文件中,并首先加载到psm1中。实际上,您可能可以使用ScriptsToProcess
PSD1元素按顺序加载这些额外文件,它们将自动包含在发布的模块中。@sage pourpre看起来我有一些研究要做。我唯一熟悉的模块是PSM1文件。从PSM1加载类已经有点奇怪了。但是,请阅读有关清单的信息。:)