PowerShell Welcome to this addition of the PowerShell ABC's where you'll find 26 posts detailing a component of the PowerShell scripting language, one letter at a time.  Today's letter is the letter "G".  For "G" I've picked a feature that was introduced in version 2.0 of the .NET Framework that allows for creating more generic types of objects.  So, today's word is "Generics".

Generics allow you to create generic objects such as collections without being constrained to the specific type of object that it contains.  Generics introduce the "type parameter" that you pass in to the creation of an object that determine the final types of some part of that said object.

generic For you non-programmers out there, you may ask yourself "So what's so great about this".  Well, think of it this way.  In the past if you wanted to create a collection class of some sort, you had to write a new version of the class for each type of object (integer, string, etc), or you had to write a single version of the class that could hold any type of object which means that a lot of custom error handling would have to be included to cover all the available types.  With generics, you can write a collection that can be constrained to only containing a specific subset of types (ie. integers and strings).

So, why would the average PowerShell developer care about accessing generic types?  Well, the most common reason is that some of the .NET classes you'll want to work with make use of generics (including PowerShell itself).

Windows PowerShell in Action by Bruce Payette includes the following examples on working with generics.

Building a generic list

The following helper function illustrates how to create a generic list.  First the full name of the generic object, in this case System.Collections.Generic.List is specified, followed by the number of type parameters (in this case one).  $base is an open generic type becuase it hasn't been bound to any type parameters.  The closed type $qt is then created by binding in the type parameters.  Once the closed type is defined, an instance of it can be created with the New-Object Cmdlet.

function New-GenericList([type] $type)
{
  $base = [System.Collections.Generic.List``1]
  $qt = $base.MakeGenericType(@($type))
  New-Object $qt
}
PS> $intList = New-GenericList int
PS> $intList.Add(1)
PS> $intList
1

Building a generic dictionary

A generic dictionary, similar to a hashtable, is made up of key/value pairs but with more control on the types of the keys and values.  In this example we'll constrain the keys to strings and the values to integers.  In this example the collection type is specified following by the number of type parameters of 2.  The two type parameters are then passed into the MakeGenericType function and finally an instance of the generic dictionary is created with the New-Object Cmdlet.

function New-GenericDictionary([type] $keyType, [type]$valueType)
{
  $base = [System.Collections.Generic.Dictionary``2]
  $ct = $base.MakeGenericType(($keyType, $valueType))
  New-Object $ct
}
PS> $gd = New-GenericDictionary string int
PS> $gd["red"] = 1
PS> $gd["blue" = 2
PS> $gd
Key         Value
--- -----
red 1
blue 2

Generics are not something that you'll likely ever need in your day to day PowerShell scripting tasks.  But, if you find yourself in that situation where you are working with a class that requires them, you'll have the tools you need to get your job done.