Sunday, September 02, 2007

Reflection on Generic, Part 2 - Reflecting Type Parameter

In the previous post, you have know how to retrieve type metadata for a generic type. In this post, let's walk through how to retrieve metadata for the type parameter. Let's use the following code as example:
public interface IPrint
{
string Print();
}
 
public class PrintingDevice<T> where T: class, IPrint, new()
{
public T Device;
}
 
public class ValueGenericType<T> where T : struct
{
public T Value;
}
 
....
 
private static void DumpType(Type t)
{
Console.WriteLine("Is Generic Type : {0}", t.IsGenericType);
Console.WriteLine("Type Name : {0}", t.FullName);
 
Type[] genericArguments = t.GetGenericArguments();
 
Console.WriteLine("Number of type parameter : {0}", genericArguments.Length);
foreach (Type typeArg in genericArguments)
{
// Check whether the current type represent a Generic Parameter.
Console.WriteLine("Is Generic Parameter : {0}", typeArg.IsGenericParameter);
 
// Get the constraint specified for type parameter
GenericParameterAttributes attr = typeArg.GenericParameterAttributes;

if ((attr & GenericParameterAttributes.DefaultConstructorConstraint) !=
GenericParameterAttributes.None)
{
Console.WriteLine("Default constructor constraint specified.");
}
 
if ((attr & GenericParameterAttributes.ReferenceTypeConstraint) !=
GenericParameterAttributes.None)
{
Console.WriteLine("Reference type constraint specified.");
}
 
if ((attr & GenericParameterAttributes.NotNullableValueTypeConstraint) !=
GenericParameterAttributes.None)
{
Console.WriteLine("Value type constraint specified.");
}
 
Type[] typeConstraints = typeArg.GetGenericParameterConstraints();
if (typeConstraints.Length > 0)
{
foreach (Type typeConstraint in typeConstraints)
{
Console.WriteLine("Type Constraint : {0}", typeConstraint.FullName);
}
}
else
{
Console.WriteLine("No type constraint specified.");
}
}
}


Run the following code with PrintingDevice,
Type t = typeof(PrintingDevice<>);
DumpType(t);

and the outcome will be :
Is Generic Type : True
Type Name : GenericConstraint.PrintingDevice`1
Number of type parameter : 1
Is Generic Parameter : True
Default constructor constraint specified.
Reference type constraint specified.
Type Constraint : GenericConstraint.IPrint


Run the code again with ValueGenericType,
Type t = typeof(ValueGenericType<>);
DumpType(t);

and the outcome will be :
Is Generic Type : True
Type Name : GenericConstraint.ValueGenericType`1
Number of type parameter : 1
Is Generic Parameter : True
Default constructor constraint specified.
Value type constraint specified.
Type Constraint : System.ValueType


Type.GetGenericArguments() will return an array of type parameters specified for the generic type.

Type.IsGenericParameter will return true if the current type represent a type parameter. If the type represent a type parameter, then the type will have no name.

Type.GenericParameterAttributes will return the constraints specified for that type parameter.

Type.GetGenericParameterConstraints() will return an array of type that are specified as the constraint for the type parameter.

Labels: , ,

0 Comments:

Post a Comment

<< Home