Generics at Runtime

Posted Saturday, August 13, 2005 7:54 PM by pwelter34
Here is a little test code that demonstrates how to use Generics at runtime. The code has two tests. The first test shows how to create a Generic Class at runtime. The second shows how to call a Generic method. Keep in mind that when using generics at runtime, there will be a reflection performance hit. 
 
~ Paul
using System;
using System.Collections.ObjectModel;
using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;
using System.Reflection;
using System.Diagnostics;

namespace GenericTest
{
    [TestClass]
    public class GenericTest
    {
        [TestMethod]
        public void CreateGenericAtRuntime()
        {
            Stopwatch watch = Stopwatch.StartNew();
            // define the generic class at runtime
            Type genericType = typeof(Collection<>).MakeGenericType(typeof(DateTime));
            // create an instance of the generic type
            object instance = Activator.CreateInstance(genericType);
            watch.Stop();

            Console.WriteLine("Dynamic Create Time: {0} ms", watch.Elapsed.TotalMilliseconds);

            Assert.IsNotNull(instance, "instance is Null");
            Assert.IsTrue(instance is Collection<DateTime>);

            Collection<DateTime> dates = instance as Collection<DateTime>;

            Assert.IsNotNull(dates, "dates is Null");

            watch = Stopwatch.StartNew();
            Collection<DateTime> d = new Collection<DateTime>();
            watch.Stop();

            Console.WriteLine("Normal Create Time: {0} ms", watch.Elapsed.TotalMilliseconds);
        }

        public Collection<T> GetCollection<T>()
        { 
            return new Collection<T>(); 
        }

        [TestMethod()]
        public void CallGenericMethodAtRuntime()
        {
            Stopwatch watch = Stopwatch.StartNew();
            MethodInfo methodInfo = typeof(GenericTest).GetMethod("GetCollection");
            MethodInfo genericInfo = methodInfo.MakeGenericMethod(typeof(DateTime));
            
            object instance = genericInfo.Invoke(this, null);
            watch.Stop();

            Console.WriteLine("Dynamic Invoke Time: {0} ms", watch.Elapsed.TotalMilliseconds);

            Assert.IsNotNull(instance, "instance is Null");
            Assert.IsTrue(instance is Collection<DateTime>);

            Collection<DateTime> dates = instance as Collection<DateTime>;

            Assert.IsNotNull(dates, "dates is Null");

            watch = Stopwatch.StartNew();
            Collection<DateTime> d = this.GetCollection<DateTime>();
            watch.Stop();

            Console.WriteLine("Normal Invoke Time: {0} ms", watch.Elapsed.TotalMilliseconds);
        }
    }
}
Filed under:

Comments

# re: Generics at Runtime

Sunday, August 14, 2005 12:05 AM by Tim Haines

Hey Paul,

I was quite happy to see in Paul Wilson's comments just now that you've started blogging. Welcome - I hope you enjoy yourself!

I love using your O/R Mapper CS templates - so I'm looking forward to learning a little more about you.

Subscribed.

Tim.

# re: Generics at Runtime

Sunday, August 14, 2005 12:06 AM by Tim Haines

Oh wait - those earlier posts are from 2004 - you're an old time blogger. ;-)

# re: Generics at Runtime

Tuesday, August 16, 2005 11:52 PM by Rick Strahl

Paul,

For creation, this should work too:

this.m_GenericEntity = Activator.CreateInstance<EntityType>();

This assume that the generic type is a class (so you need a filter).

Leave a Comment

(required) 
(required) 
(optional)
(required)