1

I can store a data type in a variable like this

$type = [int]

and use it like this:

$type.GetType().Name

but, how can I embed it in another declaration? e.g.

[Func[$type]]

* Update I *

so the invoke-expression will do the trick (thanks Mike z). what I was trying to do is create a lambda expression. this is how I can do it now:

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

but also thanks to @PetSerAl and @Jan for interesting alternatives

ekkis
  • 9,804
  • 13
  • 55
  • 105
  • Does https://stackoverflow.com/questions/19849848/powershell-how-to-create-a-delegate contain what you're looking for? – Ryan Bemrose Jun 04 '15 at 02:26

3 Answers3

3

This does not appear to be possible directly, at least according to the PowerShell 3.0 specification.

The [type] syntax is called a type-literal by the spec and its definition does not included any parts that can be expressions. It is composed of type-names which are composed of type-characters but there is nothing that is dynamic about them.

Reading through the spec, I noticed that something like this however works:

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

Now you might wonder why $type::$variable is allowed. That is because :: is an operator who's left hand side is an expression that must evaluate to a type. The right hand side is a member-name which allows simple names, string literals, and use of the subexpression operator.

However PowerShell is extremely resilient and you can do almost anything dynamicly via Invoke-Expression. Let's say you want to declare variable that is a generic delegate based on a type you know only at runtime:

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

Now $f has your delegate. You will need to test this out if $type is some complex nested or generic type but it should work for most basic types. I tested with [int] and [System.Collections.Generic.List[int]] it worked fine for both.

Mike Zboray
  • 39,828
  • 3
  • 90
  • 122
2

It can be achieved by reflection:

$type = [int]
$Func = [Func``1] # you have to use mangled name to get generic type definition.
$Func.MakeGenericType($type)
user4003407
  • 21,204
  • 4
  • 50
  • 60
1

Unfortunately, I don't thing you can do this. Have a look at this question Is possible to cast a variable to a type stored in another variable?.

There is a suggestion that a conversion is possible using Convert.ChangeType method on objects that implement IConvertible, but as far as I can tell this is not implemented in PowerShell.

You can fake it a little bit, by using your stored type in a scriptblock, but this may not be what you are after.

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

IsPublic IsSerial Name                                     BaseType                                                                                                                                                  
-------- -------- ----                                     --------                                                                                                                                                  
True     True     Byte                                     System.ValueType 
Community
  • 1
  • 1
Jan Chrbolka
  • 4,184
  • 2
  • 29
  • 38