存储数据类型并将其嵌入其他数据类型

时间:2015-06-04 01:12:32

标签: powershell

我可以将数据类型存储在像这样的变量

$type = [int]

并像这样使用它:

$type.GetType().Name

但是,如何将其嵌入另一个声明中呢? e.g。

[Func[$type]]

*更新I *

所以invoke-expression会做到这一点(感谢Mike z)。我想要做的是创建一个lambda表达式。这就是我现在可以做到的:

$exp = [System.Linq.Expressions.Expression]
$IR = [Neo4jClient.Cypher.ICypherResultItem]
Invoke-Expression "`$FuncType = [Func[$IR]]"
$ret = $exp::Lambda($FuncType, ...)

还要感谢@PetSerAl和@Jan提供有趣的替代方案

3 个答案:

答案 0 :(得分:3)

这似乎不可能直接,至少根据PowerShell 3.0 specification

规范将[type]语法称为 type-literal ,其定义不包含任何可以是表达式的部分。它由类型名称组成,它们由类型字符组成,但没有任何关于它们的动态。

通过阅读规范,我注意到这样的事情会起作用:

$type = [int]
$try = Read-Host
$type::"$(if ($try) { 'Try' } else { '' })Parse"

现在您可能想知道为什么允许$type::$variable。这是因为::是左手边的操作符,是必须求值为类型的表达式。右侧是成员名称,它允许使用简单名称,字符串文字和子表达式运算符。

然而,PowerShell非常有弹性,您可以通过Invoke-Expression动态地执行任何操作。假设你想根据你在运行时只知道的类型声明一个通用委托变量:

$type = [int] # This could come from somewhere else entirely
Invoke-Expression "`$f = [Func[$type]]{ return 1 }" 

现在$f有你的代表。如果$ type是一些复杂的嵌套类型或泛型类型,则需要对此进行测试,但它应该适用于大多数基本类型。我使用[int][System.Collections.Generic.List[int]]进行了测试,但两者都运行良好。

答案 1 :(得分:2)

可以通过反思来实现:

$type = [int]
$Func = [Func``1] # you have to use mangled name to get generic type definition.
$Func.MakeGenericType($type)

答案 2 :(得分:1)

不幸的是,我不能做到这一点。看看这个问题Is possible to cast a variable to a type stored in another variable?

有人建议在实施 IConvertible 的对象上使用 Convert.ChangeType 方法进行转换,但据我所知,这在PowerShell中未实现

你可以通过在scriptblock中使用存储的类型来伪造一点,但这可能不是你想要的。

$type = [byte]
$code = [scriptblock]::create("[$type]`$script:var = 10")
& $code
$var.gettype()

IsPublic IsSerial Name                                     BaseType                                                                                                                                                  
-------- -------- ----                                     --------                                                                                                                                                  
True     True     Byte                                     System.ValueType