August 2005 - Posts

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);
        }
    }
}
with 3 comment(s)
Filed under:
More Posts