GenericTypeParameterBuilder Class

Defines and creates generic type parameters for dynamically defined generic types and methods. This class cannot be inherited.

Inheritance Hierarchy

System.Object
  System.Reflection.MemberInfo
    System.Type
      System.Reflection.Emit.GenericTypeParameterBuilder

Namespace:  System.Reflection.Emit
Assembly:  mscorlib (in mscorlib.dll)

Syntax

'Declaration
<ComVisibleAttribute(True)> _
Public NotInheritable Class GenericTypeParameterBuilder _
    Inherits Type
[ComVisibleAttribute(true)]
public sealed class GenericTypeParameterBuilder : Type

The GenericTypeParameterBuilder type exposes the following members.

Properties

  Name Description
Public property Assembly Gets an Assembly object representing the dynamic assembly that contains the generic type definition the current type parameter belongs to. (Overrides Type.Assembly.)
Public property AssemblyQualifiedName Gets nulla null reference (Nothing in Visual Basic) in all cases. (Overrides Type.AssemblyQualifiedName.)
Public property Attributes Gets the attributes associated with the Type. (Inherited from Type.)
Public property BaseType Gets the base type constraint of the current generic type parameter. (Overrides Type.BaseType.)
Public property ContainsGenericParameters Gets true in all cases. (Overrides Type.ContainsGenericParameters.)
Public property DeclaringMethod Gets a MethodInfo that represents the declaring method, if the current GenericTypeParameterBuilder represents a type parameter of a generic method. (Overrides Type.DeclaringMethod.)
Public property DeclaringType Gets the generic type definition or generic method definition to which the generic type parameter belongs. (Overrides Type.DeclaringType.)
Public property FullName Gets nulla null reference (Nothing in Visual Basic) in all cases. (Overrides Type.FullName.)
Public property GenericParameterAttributes Gets a combination of GenericParameterAttributes flags that describe the covariance and special constraints of the current generic type parameter. (Inherited from Type.)
Public property GenericParameterPosition Gets the position of the type parameter in the type parameter list of the generic type or method that declared the parameter. (Overrides Type.GenericParameterPosition.)
Public property GUID Not supported for incomplete generic type parameters. (Overrides Type.GUID.)
Public property HasElementType Gets a value indicating whether the current Type encompasses or refers to another type; that is, whether the current Type is an array, a pointer, or is passed by reference. (Inherited from Type.)
Public property IsAbstract Gets a value indicating whether the Type is abstract and must be overridden. (Inherited from Type.)
Public property IsAnsiClass Gets a value indicating whether the string format attribute AnsiClass is selected for the Type. (Inherited from Type.)
Public property IsArray Gets a value indicating whether the Type is an array. (Inherited from Type.)
Public property IsAutoClass Gets a value indicating whether the string format attribute AutoClass is selected for the Type. (Inherited from Type.)
Public property IsAutoLayout Gets a value indicating whether the class layout attribute AutoLayout is selected for the Type. (Inherited from Type.)
Public property IsByRef Gets a value indicating whether the Type is passed by reference. (Inherited from Type.)
Public property IsClass Gets a value indicating whether the Type is a class; that is, not a value type or interface. (Inherited from Type.)
Public property IsCOMObject Gets a value indicating whether the Type is a COM object. (Inherited from Type.)
Public property IsEnum Gets a value indicating whether the current Type represents an enumeration. (Inherited from Type.)
Public property IsGenericParameter Gets true in all cases. (Overrides Type.IsGenericParameter.)
Public property IsGenericType Returns false in all cases. (Overrides Type.IsGenericType.)
Public property IsGenericTypeDefinition Gets false in all cases. (Overrides Type.IsGenericTypeDefinition.)
Public property IsImport Gets a value indicating whether the Type has a ComImportAttribute attribute applied, indicating that it was imported from a COM type library. (Inherited from Type.)
Public property IsInterface Gets a value indicating whether the Type is an interface; that is, not a class or a value type. (Inherited from Type.)
Public property IsNested Gets a value indicating whether the current Type object represents a type whose definition is nested inside the definition of another type. (Inherited from Type.)
Public property IsNestedAssembly Gets a value indicating whether the Type is nested and visible only within its own assembly. (Inherited from Type.)
Public property IsNestedFamANDAssem Gets a value indicating whether the Type is nested and visible only to classes that belong to both its own family and its own assembly. (Inherited from Type.)
Public property IsNestedFamily Gets a value indicating whether the Type is nested and visible only within its own family. (Inherited from Type.)
Public property IsNestedFamORAssem Gets a value indicating whether the Type is nested and visible only to classes that belong to either its own family or to its own assembly. (Inherited from Type.)
Public property IsNestedPrivate Gets a value indicating whether the Type is nested and declared private. (Inherited from Type.)
Public property IsNestedPublic Gets a value indicating whether a class is nested and declared public. (Inherited from Type.)
Public property IsNotPublic Gets a value indicating whether the Type is not declared public. (Inherited from Type.)
Public property IsPointer Gets a value indicating whether the Type is a pointer. (Inherited from Type.)
Public property IsPrimitive Gets a value indicating whether the Type is one of the primitive types. (Inherited from Type.)
Public property IsPublic Gets a value indicating whether the Type is declared public. (Inherited from Type.)
Public property IsSealed Gets a value indicating whether the Type is declared sealed. (Inherited from Type.)
Public property IsSpecialName Gets a value indicating whether the Type has a name that requires special handling. (Inherited from Type.)
Public property IsUnicodeClass Gets a value indicating whether the string format attribute UnicodeClass is selected for the Type. (Inherited from Type.)
Public property IsValueType Gets a value indicating whether the Type is a value type. (Inherited from Type.)
Public property IsVisible Gets a value indicating whether the Type can be accessed by code outside the assembly. (Inherited from Type.)
Public property MemberType Gets a MemberTypes value indicating that this member is a type or a nested type. (Inherited from Type.)
Public property MetadataToken Gets a value that identifies a metadata element. (Inherited from MemberInfo.)
Public property Module Gets the dynamic module that contains the generic type parameter. (Overrides Type.Module.)
Public property Name Gets the name of the generic type parameter. (Overrides MemberInfo.Name.)
Public property Namespace Gets nulla null reference (Nothing in Visual Basic) in all cases. (Overrides Type.Namespace.)
Public property ReflectedType Gets the Type object that was used to obtain the GenericTypeParameterBuilder. (Overrides Type.ReflectedType.)
Public property TypeHandle Not supported for incomplete generic type parameters. (Overrides Type.TypeHandle.)
Public property UnderlyingSystemType Gets the current generic type parameter. (Overrides Type.UnderlyingSystemType.)

Top

Methods

  Name Description
Public method Equals(Object) Tests whether the given object is an instance of EventToken and is equal to the current instance. (Overrides Type.Equals(Object).)
Public method Equals(Type) Determines if the underlying system type of the current Type is the same as the underlying system type of the specified Type. (Inherited from Type.)
Protected method Finalize Allows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.)
Public method FindMembers Returns a filtered array of MemberInfo objects of the specified member type. (Inherited from Type.)
Public method GetArrayRank Gets the number of dimensions in an Array. (Inherited from Type.)
Protected method GetAttributeFlagsImpl When overridden in a derived class, implements the Attributes property and gets a bitmask indicating the attributes associated with the Type. (Inherited from Type.)
Public method GetConstructor(array<Type[]) Searches for a public instance constructor whose parameters match the types in the specified array. (Inherited from Type.)
Public method GetConstructor(BindingFlags, Binder, array<Type[], array<ParameterModifier[]) Searches for a constructor whose parameters match the specified argument types and modifiers, using the specified binding constraints. (Inherited from Type.)
Protected method GetConstructorImpl When overridden in a derived class, searches for a constructor whose parameters match the specified argument types and modifiers, using the specified binding constraints and the specified calling convention. (Inherited from Type.)
Public method GetConstructors() Returns all the public constructors defined for the current Type. (Inherited from Type.)
Public method GetConstructors(BindingFlags) Not supported for incomplete generic type parameters. (Overrides Type.GetConstructors(BindingFlags).)
Public method GetCustomAttributes(Boolean) Not supported for incomplete generic type parameters. (Overrides MemberInfo.GetCustomAttributes(Boolean).)
Public method GetCustomAttributes(Type, Boolean) Not supported for incomplete generic type parameters. (Overrides MemberInfo.GetCustomAttributes(Type, Boolean).)
Public method GetDefaultMembers Searches for the members defined for the current Type whose DefaultMemberAttribute is set. (Inherited from Type.)
Public method GetElementType Throws a NotSupportedException in all cases. (Overrides Type.GetElementType().)
Public method GetEvent(String) Returns the EventInfo object representing the specified public event. (Inherited from Type.)
Public method GetEvent(String, BindingFlags) Not supported for incomplete generic type parameters. (Overrides Type.GetEvent(String, BindingFlags).)
Public method GetEvents() Not supported for incomplete generic type parameters. (Overrides Type.GetEvents().)
Public method GetEvents(BindingFlags) Not supported for incomplete generic type parameters. (Overrides Type.GetEvents(BindingFlags).)
Public method GetField(String) Searches for the public field with the specified name. (Inherited from Type.)
Public method GetField(String, BindingFlags) Not supported for incomplete generic type parameters. (Overrides Type.GetField(String, BindingFlags).)
Public method GetFields() Returns all the public fields of the current Type. (Inherited from Type.)
Public method GetFields(BindingFlags) Not supported for incomplete generic type parameters. (Overrides Type.GetFields(BindingFlags).)
Public method GetGenericArguments Not valid for generic type parameters. (Overrides Type.GetGenericArguments().)
Public method GetGenericParameterConstraints Returns an array of Type objects that represent the constraints on the current generic type parameter. (Inherited from Type.)
Public method GetGenericTypeDefinition Not valid for generic type parameters. (Overrides Type.GetGenericTypeDefinition().)
Public method GetHashCode Returns a 32-bit integer hash code for the current instance. (Overrides Type.GetHashCode().)
Public method GetInterface Not supported for incomplete generic type parameters. (Overrides Type.GetInterface(String, Boolean).)
Public method GetInterfaceMap Not supported for incomplete generic type parameters. (Overrides Type.GetInterfaceMap(Type).)
Public method GetInterfaces Not supported for incomplete generic type parameters. (Overrides Type.GetInterfaces().)
Public method GetMember(String) Searches for the public members with the specified name. (Inherited from Type.)
Public method GetMember(String, BindingFlags) Searches for the specified members, using the specified binding constraints. (Inherited from Type.)
Public method GetMember(String, MemberTypes, BindingFlags) Not supported for incomplete generic type parameters. (Overrides Type.GetMember(String, MemberTypes, BindingFlags).)
Public method GetMembers() Returns all the public members of the current Type. (Inherited from Type.)
Public method GetMembers(BindingFlags) Not supported for incomplete generic type parameters. (Overrides Type.GetMembers(BindingFlags).)
Public method GetMethod(String) Searches for the public method with the specified name. (Inherited from Type.)
Public method GetMethod(String, BindingFlags) Searches for the specified method, using the specified binding constraints. (Inherited from Type.)
Public method GetMethod(String, array<Type[]) Searches for the specified public method whose parameters match the specified argument types. (Inherited from Type.)
Public method GetMethod(String, array<Type[], array<ParameterModifier[]) Searches for the specified public method whose parameters match the specified argument types and modifiers. (Inherited from Type.)
Public method GetMethod(String, BindingFlags, Binder, array<Type[], array<ParameterModifier[]) Searches for the specified method whose parameters match the specified argument types and modifiers, using the specified binding constraints. (Inherited from Type.)
Public method GetMethod(String, BindingFlags, Binder, CallingConventions, array<Type[], array<ParameterModifier[]) Searches for the specified method whose parameters match the specified argument types and modifiers, using the specified binding constraints and the specified calling convention. (Inherited from Type.)
Protected method GetMethodImpl When overridden in a derived class, searches for the specified method whose parameters match the specified argument types and modifiers, using the specified binding constraints and the specified calling convention. (Inherited from Type.)
Public method GetMethods() Returns all the public methods of the current Type. (Inherited from Type.)
Public method GetMethods(BindingFlags) Not supported for incomplete generic type parameters. (Overrides Type.GetMethods(BindingFlags).)
Public method GetNestedType Not supported for incomplete generic type parameters. (Overrides Type.GetNestedType(String, BindingFlags).)
Public method GetNestedTypes Not supported for incomplete generic type parameters. (Overrides Type.GetNestedTypes(BindingFlags).)
Public method GetProperties() Returns all the public properties of the current Type. (Inherited from Type.)
Public method GetProperties(BindingFlags) Not supported for incomplete generic type parameters. (Overrides Type.GetProperties(BindingFlags).)
Public method GetProperty(String) Searches for the public property with the specified name. (Inherited from Type.)
Public method GetProperty(String, BindingFlags) Searches for the specified property, using the specified binding constraints. (Inherited from Type.)
Public method GetProperty(String, Type) Searches for the public property with the specified name and return type. (Inherited from Type.)
Public method GetProperty(String, Type, array<Type[]) Searches for the specified public property whose parameters match the specified argument types. (Inherited from Type.)
Public method GetProperty(String, Type, array<Type[], array<ParameterModifier[]) Searches for the specified public property whose parameters match the specified argument types and modifiers. (Inherited from Type.)
Public method GetProperty(String, BindingFlags, Binder, Type, array<Type[], array<ParameterModifier[]) Searches for the specified property whose parameters match the specified argument types and modifiers, using the specified binding constraints. (Inherited from Type.)
Protected method GetPropertyImpl When overridden in a derived class, searches for the specified property whose parameters match the specified argument types and modifiers, using the specified binding constraints. (Inherited from Type.)
Public method GetType() Gets the current Type. (Inherited from Type.)
Protected method HasElementTypeImpl When overridden in a derived class, implements the HasElementType property and determines whether the current Type encompasses or refers to another type; that is, whether the current Type is an array, a pointer, or is passed by reference. (Inherited from Type.)
Public method InvokeMember(String, BindingFlags, Binder, Object, array<Object[]) Invokes the specified member, using the specified binding constraints and matching the specified argument list. (Inherited from Type.)
Public method InvokeMember(String, BindingFlags, Binder, Object, array<Object[], array<ParameterModifier[], CultureInfo, array<String[]) Not supported for incomplete generic type parameters. (Overrides Type.InvokeMember(String, BindingFlags, Binder, Object, array<Object[], array<ParameterModifier[], CultureInfo, array<String[]).)
Protected method IsArrayImpl When overridden in a derived class, implements the IsArray property and determines whether the Type is an array. (Inherited from Type.)
Public method IsAssignableFrom Not supported for incomplete generic type parameters. (Overrides Type.IsAssignableFrom(Type).)
Protected method IsByRefImpl When overridden in a derived class, implements the IsByRef property and determines whether the Type is passed by reference. (Inherited from Type.)
Protected method IsCOMObjectImpl When overridden in a derived class, implements the IsCOMObject property and determines whether the Type is a COM object. (Inherited from Type.)
Public method IsDefined Not supported for incomplete generic type parameters. (Overrides MemberInfo.IsDefined(Type, Boolean).)
Public method IsInstanceOfType Determines whether the specified object is an instance of the current Type. (Inherited from Type.)
Protected method IsPointerImpl When overridden in a derived class, implements the IsPointer property and determines whether the Type is a pointer. (Inherited from Type.)
Protected method IsPrimitiveImpl When overridden in a derived class, implements the IsPrimitive property and determines whether the Type is one of the primitive types. (Inherited from Type.)
Public method IsSubclassOf Not supported for incomplete generic type parameters. (Overrides Type.IsSubclassOf(Type).)
Protected method IsValueTypeImpl Implements the IsValueType property and determines whether the Type is a value type; that is, not a class or an interface. (Inherited from Type.)
Public method MakeArrayType() Returns the type of a one-dimensional array whose element type is the generic type parameter. (Overrides Type.MakeArrayType().)
Public method MakeArrayType(Int32) Returns the type of an array whose element type is the generic type parameter, with the specified number of dimensions. (Overrides Type.MakeArrayType(Int32).)
Public method MakeByRefType Returns a Type object that represents the current generic type parameter when passed as a reference parameter. (Overrides Type.MakeByRefType().)
Public method MakeGenericType Not valid for incomplete generic type parameters. (Overrides Type.MakeGenericType(array<Type[]).)
Public method MakePointerType Returns a Type object that represents a pointer to the current generic type parameter. (Overrides Type.MakePointerType().)
Protected method MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)
Public method SetBaseTypeConstraint Sets the base type that a type must inherit in order to be substituted for the type parameter.
Public method SetCustomAttribute Set a custom attribute using a custom attribute builder.
Public method SetGenericParameterAttributes Sets the variance characteristics and special constraints of the generic parameter, such as the parameterless constructor constraint.
Public method SetInterfaceConstraints Sets the interfaces a type must implement in order to be substituted for the type parameter.
Public method ToString Returns a string representation of the current generic type parameter. (Overrides Type.ToString().)

Top

Remarks

You can get an array of GenericTypeParameterBuilder objects by using the TypeBuilder.DefineGenericParameters method to add type parameters to a dynamic type, thus making it a generic type, or by using the MethodBuilder.DefineGenericParameters method to add type parameters to a dynamic method. Use the GenericTypeParameterBuilder objects to add constraints to the type parameters. Constraints are of three kinds:

  • The base type constraint specifies that any type assigned to the generic type parameter must derive from a particular base type. Set this constraint by using the SetBaseTypeConstraint method.

  • An interface constraint specifies that any type assigned to the generic type parameter must implement a particular interface. Set the interface constraints by using the SetInterfaceConstraints method.

  • Special constraints specify that any type assigned to the generic type parameter must have a default constructor, must be a reference type, or must be a value type. Set the special constraints for a type parameter by using the SetGenericParameterAttributes method.

Interface constraints and special constraints cannot be retrieved using methods of the GenericTypeParameterBuilder class. Once you have created the generic type that contains the type parameters, you can use its Type object to reflect the constraints. Use the Type.GetGenericArguments method to get the type parameters, and for each type parameter use the Type.GetGenericParameterConstraints method to get the base type constraint and interface constraints, and the Type.GenericParameterAttributes property to get the special constraints.

Examples

The following code example creates a generic type with two type parameters. For a more detailed explanation of the steps involved in defining a dynamic generic type, see How to: Define a Generic Type with Reflection Emit.

Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Collections.Generic

' Define a trivial base class and two trivial interfaces 
' to use when demonstrating constraints.
'
Public Class ExampleBase
End Class

Public Interface IExampleA
End Interface

Public Interface IExampleB
End Interface

' Define a trivial type that can substitute for type parameter 
' TSecond.
'
Public Class ExampleDerived
   Inherits ExampleBase
   Implements IExampleA, IExampleB
End Class

Public Class Example

   ' Make the output TextBlock available to all methods.
   Private Shared outputBlock As System.Windows.Controls.TextBlock

   Public Shared Sub Demo(ByVal output As System.Windows.Controls.TextBlock)

      outputBlock = output

      ' Define a dynamic assembly to contain the sample type. In Silverlight, 
      ' a dynamic assembly has only one module. 
      '
      Dim myDomain As AppDomain = AppDomain.CurrentDomain
      Dim myAsmName As New AssemblyName("GenericEmitExample1")
      Dim myAssembly As AssemblyBuilder = myDomain.DefineDynamicAssembly( _
          myAsmName, _
          AssemblyBuilderAccess.Run)
      Dim myModule As ModuleBuilder = myAssembly.DefineDynamicModule( _
          myAsmName.Name)

      ' Get type objects for the base class trivial interfaces to
      ' be used as constraints.
      '
      Dim baseType As Type = GetType(ExampleBase)
      Dim interfaceA As Type = GetType(IExampleA)
      Dim interfaceB As Type = GetType(IExampleB)

      ' Define the sample type.
      '
      Dim myType As TypeBuilder = myModule.DefineType( _
          "Sample", _
          TypeAttributes.Public)

      outputBlock.Text &= String.Format("Type 'Sample' is generic: {0}", _
          myType.IsGenericType) & vbCrLf

      ' Define type parameters for the type. Until you do this, 
      ' the type is not generic, as the preceding and following 
      ' WriteLine statements show. The type parameter names are
      ' specified as an array of strings. To make the code
      ' easier to read, each GenericTypeParameterBuilder is placed
      ' in a variable with the same name as the type parameter.
      ' 
      Dim typeParamNames() As String = {"TFirst", "TSecond"}
      Dim typeParams() As GenericTypeParameterBuilder = _
          myType.DefineGenericParameters(typeParamNames)

      Dim TFirst As GenericTypeParameterBuilder = typeParams(0)
      Dim TSecond As GenericTypeParameterBuilder = typeParams(1)

      outputBlock.Text &= String.Format("Type 'Sample' is generic: {0}", _
          myType.IsGenericType) & vbCrLf

      ' Apply constraints to the type parameters.
      '
      ' A type that is substituted for the first parameter, TFirst,
      ' must be a reference type and must have a parameterless
      ' constructor.
      TFirst.SetGenericParameterAttributes( _
          GenericParameterAttributes.DefaultConstructorConstraint _
          Or GenericParameterAttributes.ReferenceTypeConstraint)

      ' A type that is substituted for the second type
      ' parameter must implement IExampleA and IExampleB, and
      ' inherit from the trivial test class ExampleBase. The
      ' interface constraints are specified as an array 
      ' containing the interface types.
      TSecond.SetBaseTypeConstraint(baseType)
      Dim interfaceTypes() As Type = {interfaceA, interfaceB}
      TSecond.SetInterfaceConstraints(interfaceTypes)

      ' The following code adds a private field named ExampleField,
      ' of type TFirst.
      Dim exField As FieldBuilder = _
          myType.DefineField("ExampleField", TFirst, _
              FieldAttributes.Private)

      ' Define a Shared method that takes an array of TFirst and 
      ' returns a List(Of TFirst) containing all the elements of 
      ' the array. To define this method it is necessary to create
      ' the type List(Of TFirst) by calling MakeGenericType on the
      ' generic type definition, List(Of T). (The T is omitted with
      ' the GetType operator when you get the generic type 
      ' definition.) The parameter type is created by using the
      ' MakeArrayType method. 
      '
      Dim listOf As Type = GetType(List(Of ))
      Dim listOfTFirst As Type = listOf.MakeGenericType(TFirst)
      Dim mParamTypes() As Type = {TFirst.MakeArrayType()}

      Dim exMethod As MethodBuilder = _
          myType.DefineMethod("ExampleMethod", _
              MethodAttributes.Public Or MethodAttributes.Static, _
              listOfTFirst, _
              mParamTypes)

      ' Emit the method body. 
      ' The method body consists of just three opcodes, to load 
      ' the input array onto the execution stack, to call the 
      ' List(Of TFirst) constructor that takes IEnumerable(Of TFirst),
      ' which does all the work of putting the input elements into
      ' the list, and to return, leaving the list on the stack. The
      ' hard work is getting the constructor.
      ' 
      ' The GetConstructor method is not supported on a 
      ' GenericTypeParameterBuilder, so it is not possible to get 
      ' the constructor of List(Of TFirst) directly. There are two
      ' steps, first getting the constructor of List(Of T) and then
      ' calling a method that converts it to the corresponding 
      ' constructor of List(Of TFirst).
      '
      ' The constructor needed here is the one that takes an
      ' IEnumerable(Of T). Note, however, that this is not the 
      ' generic type definition of IEnumerable(Of T); instead, the
      ' T from List(Of T) must be substituted for the T of 
      ' IEnumerable(Of T). (This seems confusing only because both
      ' types have type parameters named T. That is why this example
      ' uses the somewhat silly names TFirst and TSecond.) To get
      ' the type of the constructor argument, take the generic
      ' type definition IEnumerable(Of T) (expressed as 
      ' IEnumerable(Of ) when you use the GetType operator) and 
      ' call MakeGenericType with the first generic type parameter
      ' of List(Of T). The constructor argument list must be passed
      ' as an array, with just one argument in this case.
      ' 
      ' Now it is possible to get the constructor of List(Of T),
      ' using GetConstructor on the generic type definition. To get
      ' the constructor of List(Of TFirst), pass List(Of TFirst) and
      ' the constructor from List(Of T) to the static
      ' TypeBuilder.GetConstructor method.
      '
      Dim ilgen As ILGenerator = exMethod.GetILGenerator()

      Dim ienumOf As Type = GetType(IEnumerable(Of ))
      Dim listOfTParams() As Type = listOf.GetGenericArguments()
      Dim TfromListOf As Type = listOfTParams(0)
      Dim ienumOfT As Type = ienumOf.MakeGenericType(TfromListOf)
      Dim ctorArgs() As Type = {ienumOfT}

      Dim ctorPrep As ConstructorInfo = _
          listOf.GetConstructor(ctorArgs)
      Dim ctor As ConstructorInfo = _
          TypeBuilder.GetConstructor(listOfTFirst, ctorPrep)

      ilgen.Emit(OpCodes.Ldarg_0)
      ilgen.Emit(OpCodes.Newobj, ctor)
      ilgen.Emit(OpCodes.Ret)

      ' Create the type. 
      Dim finished As Type = myType.CreateType()

      ' Invoke the method.
      ' ExampleMethod is not generic, but the type it belongs to is
      ' generic, so in order to get a MethodInfo that can be invoked
      ' it is necessary to create a constructed type. The Example 
      ' class satisfies the constraints on TFirst, because it is a 
      ' reference type and has a default constructor. In order to
      ' have a class that satisfies the constraints on TSecond, 
      ' this code example defines the ExampleDerived type. These
      ' two types are passed to MakeGenericMethod to create the
      ' constructed type.
      '
      Dim typeArgs() As Type = _
          {GetType(Example), GetType(ExampleDerived)}
      Dim constructed As Type = finished.MakeGenericType(typeArgs)
      Dim mi As MethodInfo = constructed.GetMethod("ExampleMethod")

      ' Create an array of Example objects, as input to the generic
      ' method. This array must be passed as the only element of an 
      ' array of arguments. The first argument of Invoke is 
      ' Nothing, because ExampleMethod is Shared. Display the count
      ' on the resulting List(Of Example).
      ' 
      Dim input() As Example = {New Example(), New Example()}
      Dim arguments() As Object = {input}

      Dim listX As List(Of Example) = mi.Invoke(Nothing, arguments)

      outputBlock.Text &= String.Format(vbLf & _
          "There are {0} elements in the List(Of Example).", _
          listX.Count _
      ) & vbCrLf

      DisplayGenericParameters(finished)

   End Sub


   Private Shared Sub DisplayGenericParameters(ByVal t As Type)

      If Not t.IsGenericType Then
         outputBlock.Text &= String.Format("Type '{0}' is not generic.") & vbCrLf
         Return
      End If
      If Not t.IsGenericTypeDefinition Then _
          t = t.GetGenericTypeDefinition()

      Dim typeParameters() As Type = t.GetGenericArguments()
      outputBlock.Text &= String.Format(vbCrLf & _
          "Listing {0} type parameters for type '{1}'.", _
          typeParameters.Length, t) & vbCrLf

      For Each tParam As Type In typeParameters

         outputBlock.Text &= String.Format(vbCrLf & "Type parameter {0}:", _
             tParam.ToString()) & vbCrLf

         For Each c As Type In tParam.GetGenericParameterConstraints()
            If c.IsInterface Then
               outputBlock.Text &= String.Format("    Interface constraint: {0}", c) & vbCrLf
            Else
               outputBlock.Text &= String.Format("    Base type constraint: {0}", c) & vbCrLf
            End If
         Next

         ListConstraintAttributes(tParam)
      Next tParam
   End Sub


   ' List the constraint flags. The GenericParameterAttributes
   ' enumeration contains two sets of attributes, variance and
   ' constraints. For this example, only constraints are used.
   '
   Private Shared Sub ListConstraintAttributes(ByVal t As Type)

      ' Mask off the constraint flags. 
      Dim constraints As GenericParameterAttributes = _
          t.GenericParameterAttributes And _
          GenericParameterAttributes.SpecialConstraintMask

      If (constraints And GenericParameterAttributes.ReferenceTypeConstraint) _
              <> GenericParameterAttributes.None Then _
          outputBlock.Text &= "    ReferenceTypeConstraint" & vbCrLf

      If (constraints And GenericParameterAttributes.NotNullableValueTypeConstraint) _
              <> GenericParameterAttributes.None Then _
          outputBlock.Text &= "    NotNullableValueTypeConstraint" & vbCrLf

      If (constraints And GenericParameterAttributes.DefaultConstructorConstraint) _
              <> GenericParameterAttributes.None Then _
          outputBlock.Text &= "    DefaultConstructorConstraint" & vbCrLf

   End Sub

End Class

' This code example produces output similar to the following:
'
'Type 'Sample' is generic: False
'Type 'Sample' is generic: True
'
'There are 2 elements in the List(Of Example).
'
'Listing 2 type parameters for type 'Sample[TFirst,TSecond]'.
'
'Type parameter TFirst:
'    ReferenceTypeConstraint
'    DefaultConstructorConstraint
'
'Type parameter TSecond:
'    Interface constraint: SilverlightApplication.IExampleA
'    Interface constraint: SilverlightApplication.IExampleB
'    Base type constraint: SilverlightApplication.ExampleBase
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;

// Define a trivial base class and two trivial interfaces 
// to use when demonstrating constraints.
//
public class ExampleBase { }

public interface IExampleA { }

public interface IExampleB { }

// Define a trivial type that can substitute for type parameter 
// TSecond.
//
public class ExampleDerived : ExampleBase, IExampleA, IExampleB { }


public class Example
{
   // Make the output TextBlock available to all methods.
   private static System.Windows.Controls.TextBlock outputBlock;

   public static void Demo(System.Windows.Controls.TextBlock output)
   {
      outputBlock = output;

      // Define a dynamic assembly to contain the sample type. In Silverlight,
      // a dynamic assembly contains one module.
      //
      AppDomain myDomain = AppDomain.CurrentDomain;
      AssemblyName myAsmName = new AssemblyName("GenericEmitExample1");
      AssemblyBuilder myAssembly =
          myDomain.DefineDynamicAssembly(myAsmName,
              AssemblyBuilderAccess.Run);
      ModuleBuilder myModule =
          myAssembly.DefineDynamicModule(myAsmName.Name);

      // Get type objects for the base class trivial interfaces to
      // be used as constraints.
      //
      Type baseType = typeof(ExampleBase);
      Type interfaceA = typeof(IExampleA);
      Type interfaceB = typeof(IExampleB);

      // Define the sample type.
      //
      TypeBuilder myType =
          myModule.DefineType("Sample", TypeAttributes.Public);

      outputBlock.Text += String.Format("Type 'Sample' is generic: {0}",
          myType.IsGenericType) + "\n";

      // Define type parameters for the type. Until you do this, 
      // the type is not generic, as the preceding and following 
      // WriteLine statements show. The type parameter names are
      // specified as an array of strings. To make the code
      // easier to read, each GenericTypeParameterBuilder is placed
      // in a variable with the same name as the type parameter.
      // 
      string[] typeParamNames = { "TFirst", "TSecond" };
      GenericTypeParameterBuilder[] typeParams =
          myType.DefineGenericParameters(typeParamNames);

      GenericTypeParameterBuilder TFirst = typeParams[0];
      GenericTypeParameterBuilder TSecond = typeParams[1];

      outputBlock.Text += String.Format("Type 'Sample' is generic: {0}",
          myType.IsGenericType) + "\n";

      // Apply constraints to the type parameters.
      //
      // A type that is substituted for the first parameter, TFirst,
      // must be a reference type and must have a parameterless
      // constructor.
      TFirst.SetGenericParameterAttributes(
          GenericParameterAttributes.DefaultConstructorConstraint |
          GenericParameterAttributes.ReferenceTypeConstraint);

      // A type that is substituted for the second type
      // parameter must implement IExampleA and IExampleB, and
      // inherit from the trivial test class ExampleBase. The
      // interface constraints are specified as an array 
      // containing the interface types.
      TSecond.SetBaseTypeConstraint(baseType);
      Type[] interfaceTypes = { interfaceA, interfaceB };
      TSecond.SetInterfaceConstraints(interfaceTypes);

      // The following code adds a private field named ExampleField,
      // of type TFirst.
      FieldBuilder exField =
          myType.DefineField("ExampleField", TFirst,
              FieldAttributes.Private);

      // Define a static method that takes an array of TFirst and 
      // returns a List<TFirst> containing all the elements of 
      // the array. To define this method it is necessary to create
      // the type List<TFirst> by calling MakeGenericType on the
      // generic type definition, List<T>. (The T is omitted with
      // the typeof operator when you get the generic type 
      // definition.) The parameter type is created by using the
      // MakeArrayType method. 
      //
      Type listOf = typeof(List<>);
      Type listOfTFirst = listOf.MakeGenericType(TFirst);
      Type[] mParamTypes = { TFirst.MakeArrayType() };

      MethodBuilder exMethod =
          myType.DefineMethod("ExampleMethod",
              MethodAttributes.Public | MethodAttributes.Static,
              listOfTFirst,
              mParamTypes);

      // Emit the method body. 
      // The method body consists of just three opcodes, to load 
      // the input array onto the execution stack, to call the 
      // List<TFirst> constructor that takes IEnumerable<TFirst>,
      // which does all the work of putting the input elements into
      // the list, and to return, leaving the list on the stack. The
      // hard work is getting the constructor.
      // 
      // The GetConstructor method is not supported on a 
      // GenericTypeParameterBuilder, so it is not possible to get 
      // the constructor of List<TFirst> directly. There are two
      // steps, first getting the constructor of List<T> and then
      // calling a method that converts it to the corresponding 
      // constructor of List<TFirst>.
      //
      // The constructor needed here is the one that takes an
      // IEnumerable<T>. Note, however, that this is not the 
      // generic type definition of IEnumerable<T>; instead, the
      // T from List<T> must be substituted for the T of 
      // IEnumerable<T>. (This seems confusing only because both
      // types have type parameters named T. That is why this example
      // uses the somewhat silly names TFirst and TSecond.) To get
      // the type of the constructor argument, take the generic
      // type definition IEnumerable<T> (expressed as 
      // IEnumerable<> when you use the typeof operator) and 
      // call MakeGenericType with the first generic type parameter
      // of List<T>. The constructor argument list must be passed
      // as an array, with just one argument in this case.
      // 
      // Now it is possible to get the constructor of List<T>,
      // using GetConstructor on the generic type definition. To get
      // the constructor of List<TFirst>, pass List<TFirst> and
      // the constructor from List<T> to the static
      // TypeBuilder.GetConstructor method.
      //
      ILGenerator ilgen = exMethod.GetILGenerator();

      Type ienumOf = typeof(IEnumerable<>);
      Type TfromListOf = listOf.GetGenericArguments()[0];
      Type ienumOfT = ienumOf.MakeGenericType(TfromListOf);
      Type[] ctorArgs = { ienumOfT };

      ConstructorInfo ctorPrep = listOf.GetConstructor(ctorArgs);
      ConstructorInfo ctor =
          TypeBuilder.GetConstructor(listOfTFirst, ctorPrep);

      ilgen.Emit(OpCodes.Ldarg_0);
      ilgen.Emit(OpCodes.Newobj, ctor);
      ilgen.Emit(OpCodes.Ret);

      // Create the type. 
      Type finished = myType.CreateType();

      // Invoke the method.
      // ExampleMethod is not generic, but the type it belongs to is
      // generic, so in order to get a MethodInfo that can be invoked
      // it is necessary to create a constructed type. The Example 
      // class satisfies the constraints on TFirst, because it is a 
      // reference type and has a default constructor. In order to
      // have a class that satisfies the constraints on TSecond, 
      // this code example defines the ExampleDerived type. These
      // two types are passed to MakeGenericMethod to create the
      // constructed type.
      //
      Type[] typeArgs = { typeof(Example), typeof(ExampleDerived) };
      Type constructed = finished.MakeGenericType(typeArgs);
      MethodInfo mi = constructed.GetMethod("ExampleMethod");

      // Create an array of Example objects, as input to the generic
      // method. This array must be passed as the only element of an 
      // array of arguments. The first argument of Invoke is 
      // null, because ExampleMethod is static. Display the count
      // on the resulting List<Example>.
      // 
      Example[] input = { new Example(), new Example() };
      object[] arguments = { input };

      List<Example> listX =
          (List<Example>)mi.Invoke(null, arguments);

      outputBlock.Text += String.Format(
          "\nThere are {0} elements in the List<Example>.",
          listX.Count) + "\n";

      DisplayGenericParameters(finished);
   }

   private static void DisplayGenericParameters(Type t)
   {
      if (!t.IsGenericType)
      {
         outputBlock.Text += String.Format("Type '{0}' is not generic.") + "\n";
         return;
      }
      if (!t.IsGenericTypeDefinition)
      {
         t = t.GetGenericTypeDefinition();
      }

      Type[] typeParameters = t.GetGenericArguments();
      outputBlock.Text += String.Format("\nListing {0} type parameters for type '{1}'.",
          typeParameters.Length, t) + "\n";

      foreach (Type tParam in typeParameters)
      {
         outputBlock.Text += String.Format("\r\nType parameter {0}:", tParam.ToString()) + "\n";

         foreach (Type c in tParam.GetGenericParameterConstraints())
         {
            if (c.IsInterface)
            {
               outputBlock.Text += String.Format("    Interface constraint: {0}", c) + "\n";
            }
            else
            {
               outputBlock.Text += String.Format("    Base type constraint: {0}", c) + "\n";
            }
         }

         ListConstraintAttributes(tParam);
      }
   }

   // List the constraint flags. The GenericParameterAttributes
   // enumeration contains two sets of attributes, variance and
   // constraints. For this example, only constraints are used.
   //
   private static void ListConstraintAttributes(Type t)
   {
      // Mask off the constraint flags. 
      GenericParameterAttributes constraints =
          t.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;

      if ((constraints & GenericParameterAttributes.ReferenceTypeConstraint)
          != GenericParameterAttributes.None)
      {
         outputBlock.Text += "    ReferenceTypeConstraint" + "\n";
      }

      if ((constraints & GenericParameterAttributes.NotNullableValueTypeConstraint)
          != GenericParameterAttributes.None)
      {
         outputBlock.Text += "    NotNullableValueTypeConstraint" + "\n";
      }

      if ((constraints & GenericParameterAttributes.DefaultConstructorConstraint)
          != GenericParameterAttributes.None)
      {
         outputBlock.Text += "    DefaultConstructorConstraint" + "\n";
      }
   }
}

/* This code example produces the following output:

Type 'Sample' is generic: False
Type 'Sample' is generic: True

There are 2 elements in the List<Example>.

Listing 2 type parameters for type 'Sample[TFirst,TSecond]'.

Type parameter TFirst:
    ReferenceTypeConstraint
    DefaultConstructorConstraint

Type parameter TSecond:
    Interface constraint: IExampleA
    Interface constraint: IExampleB
    Base type constraint: ExampleBase
 */

Version Information

Silverlight

Supported in: 5, 4, 3

Platforms

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.

Thread Safety

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.