When you work with the .NET Framework, you’ll often run across classes that have the primary responsibility of managing other objects. For example, the System. Collections.ArrayList class lets you manage a dynamic list of objects. You can add objects to an ArrayList, remove objects from it, sort the objects inside, and more. These objects can be any type of object—String objects, integers, DateTime objects, and many more. However, working with classes that support arbitrary objects can sometimes be a little awkward. One example is type safety: if you accidentally add a String to a list of integers, you might not find out until your program fails.
Although the issue becomes largely moot when working only inside PowerShell, a more common complaint in strongly typed languages (such as C#) is that you have to remind the environment (through explicit casts) about the type of your object when you work with it again:
// This is C# code
System.Collections.ArrayList list =
new System.Collections.ArrayList();
list.Add("Hello World");
string result = (String) list[0];
To address these problems, the .NET Framework introduced a feature called generic types: classes that support arbitrary types of objects, but allow you to specify which type of object. In this case, a collection of strings:
// This is C# code System.Collections.ObjectModel.Collection<String> list = new System.Collections.ObjectModel.Collection<String>(); list.Add("Hello World");
string result = list[0]; Although the NewObject cmdlet is powerful, it doesn’t yet handle creating generic types very elegantly. For a simple generic type, you can use the syntax that the .NET Framework uses under the hood:
$coll = NewObject 'System.Collections.ObjectModel.Collection`1[System.String]'
However, that begins to fall apart if you want to use types defined outside the main mscorlib assembly, or want to create complex generic types (for example, ones that refer to other generic types).
Example 33. NewGenericObject.ps1
############################################################################## ## ## NewGenericObject.ps1 ## ## Creates an object of a generic type: ## ## Usage:
##
##
# Simple generic collection
##
NewGenericObject System.Collections.ObjectModel.Collection System.Int32
##
##
# Generic dictionary with two types
##
NewGenericObject System.Collections.Generic.Dictionary `
##
System.String,System.Int32
##
##
# Generic list as the second type to a generic dictionary
##
$secondType = NewGenericObject System.Collections.Generic.List Int32
##
NewGenericObject System.Collections.Dictionary `
##
System.String,$secondType.GetType()
##
##
# Generic type with a nondefault constructor
##
NewGenericObject System.Collections.Generic.LinkedListNode `
##
System.String "Hi"
##
##############################################################################