PowerShell Reflection-Lite

hand mirror with reflectionN.B. This is just a quick note to relate something I ran into in the last couple of weeks. Not an in-depth discussion of reflection.

Reflection

Reflection is an interesting meta-programming tool. Using it, we can find (among other things) a constructor or method that matches whatever criteria we want including name, # of parameters, types of parameters, public/private, etc. As you can imagine, using reflection can be a chore.

I have never had to use reflection in PowerShell. Usually, `Get-Member` is enough to get me what I need.

Dynamic Commands in PowerShell

I have also talked before about how PowerShell lets you by dynamic in ways that are remarkably easy.

For instance, you can invoke an arbitrary command with arbitrary arguments with a command object (from `Get-Command`), and a hashtable of parameter/argument mappings simply using `& $cmd @params`.

That’s crazy easy. Maybe I’ve missed that kind of functionality in other languages and it’s been there, but I don’t think so. At least not often.

I had also seen that the following work fine:

$hash=@{A=1;B=1}
$prop='A'

#use the key as a property
$hash['A'] -eq $hash.A

#use a variable as a property name
$hash['A'] -eq $hash.$prop

#use a string literal as a property name
$hash['A'] -eq $hash.'A'

What I found

I was working on some dynamic WPF suff (posts coming this week, I promise) and needed to add an event handler to a control. The problem was that the specific event I was adding a handler for was a parameter. In case you didn’t know, adding an event handler to a WPF control looks something like this (we’ll use the TextChanged event):

  $textbox.Add_ContentChanged({scriptblock})

Or, if you prefer, you can omit the parentheses if the only parameter is a scriptblock:

  $textbox.Add_ContentChanged{scriptblock}

The issue was that the name of the method is different for each event. I thought “Oh, no! I’m going to have to use reflection”.

But then I thought…I wonder if PowerShell has already taken care of this. I tried the following:

# $control, $eventName, and $action were parameters 
$control."Add_$EventName"($action)

I figured that the worst that could happen was that it would blow up and I’d dig out a reference on using reflection (and probably translate from C#).

Instead, it worked like a charm.

Chalk another win up for the PowerShell team. In case you hadn’t noticed, they do good work.

–Mike