Paolo Pialorsi - Bridge The Gap!

Living in a Service Oriented World

Working with Dynamic C# 2.0 Generics

Yesterday I was involved in working with dynamic generic types for a project I'm working on. At least I achieved this solution to dinamically create a Generic Type for instance reading a .config file:

using System;
using System.Collections.Generic;
using System.Text;

namespace DynamicGeneric
{
 class Program
 {
  static void Main(string[] args)
  {
   // "Standard" generic instantiation
   GenericClass<PaoloEntity> paoloGenericClass = new GenericClass<PaoloEntity>();
   Console.WriteLine(paoloGenericClass.GetEntity());

   // Create a parametric generic type instance
   Type paoloEntityType = Type.GetType("DynamicGeneric.PaoloEntity, DynamicGeneric");
   Type paoloGenericClassType = typeof(GenericClass<>).MakeGenericType(paoloEntityType);
   Object paoloGenericClassDynamic = Activator.CreateInstance(paoloGenericClassType);
   Console.WriteLine(paoloGenericClassDynamic.ToString());
   GenericClass<PaoloEntity> paoloGenericClassDynamic2 = (GenericClass<PaoloEntity>)paoloGenericClassDynamic;
   Console.WriteLine(paoloGenericClassDynamic2.GetEntity());
  }
 }

 public class BaseEntity
 {
  private String _name;

  public String Name
  {
   get { return(this._name); }
   set { this._name = value; }
  }
 }

 public class PaoloEntity: BaseEntity
 {
  public PaoloEntity()
  {
   this.Name = "Paolo";
  }

  public override string ToString()
  {
   return (String.Format("Entity: {0}", this.Name));
  }
 }

 public class GenericClass<TEntity>
  where TEntity : BaseEntity, new()
 {
  public TEntity GetEntity()
  {
   return (new TEntity());
  }
 }
}

The only last problem I'm facing on is the ability not only to create an instance but also to declare a Generic Type dinamically. I mean something like:

GenericClass<typeof(paoloGenericClassType)> paoloGenericClassDynamic = ....

Of course the above line does not compile, because the compiler needs to know the generic parameter type provided to the Generic Type called "GenericClass" (I guess). On the other side I don't want to declare my Generic Type instance as an Object ... I'd loose all the benefits of generics ..... Any idea?

Update: of course I know that I can use a base class or interface for my GenericClass, in order to have a common signature for my GetEntity method instead of having just an Object. The problem that I've in my real application (not in the snippet published here) is that my GenericClass (that in reality are many classes) have a base interface that is based on generics too... probably I'm wondering too much from my life! :-)

Posted: Jun 11 2005, 10:39 AM by paolopia | with 7 comment(s)
Filed under:

Comments

TrackBack said:

# June 10, 2005 10:41 PM

Kyle said:

Great Article This code must be for LLBL because this is exactly what I was looking for. Keep up the good work you saved me a big headache

# July 15, 2007 5:55 AM

iw said:

hah! been trying to figure the same problem.

Haven't found a solution yet.

# August 23, 2007 1:04 PM

Derek said:

Here's the solution:

class Program

{

static void Main( string[] args )

{

Type t = typeof( MyClass );

MethodInfo mi = t.GetMethod( "GetTypeOf" );

MethodInfo mi1 = mi.MakeGenericMethod( typeof( string ) );

string s = (string)mi1.Invoke( new MyClass(), new object[ 0 ] );

}

public class MyClass

{

public string GetTypeOf<T>() where T : class

{

return typeof( T ).AssemblyQualifiedName;

}

}

}

# November 9, 2007 9:20 AM

Derek said:

Ooops!  I forgot to mention that this example is for a generic method.  To do the same thing with a generic class, you have a corresponding method on the Type class called MakeGenericType that does the generic-class equivalent of what MethodInfo.MakeGenericMethod does.

The key to understanding this solution is to understand the difference between a Type or MethodInfo that describes an "unconstructed" generic type, and one that describes a "constructed" generic type.  If the generic parameter T (in my example) has not been defined with a type, then the methodInfo for that method is "unconstructed".  You need to call MakeGenericMethod to fill in the types and get a MethodInfo that can be invoked.  Ditto for the Type and MakeGenericType.

# November 9, 2007 12:36 PM

Stefano Bonazzi said:

Hello, did you find the answer for GenericClass<typeof(paoloGenericClassType)> paoloGenericClassDynamic =....

?

# August 27, 2008 10:05 AM

theBorne said:

Did you find the answer for GenericClass<typeof(paoloGenericClassType)> paoloGenericClassDynamic =....

I am wondering this too - did you find the answer??? Halp!

# October 30, 2008 12:43 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)