views:

889

answers:

4

I need to pass a generic type parameter to an interface. I have a string with the name of the type.

I have something like this:

string type = "ClassType";
Type t = Type.GetType("ClassType");

IProvider<t> provider = (IProvider<t>)someObject;

This doesn't work for me. What is the correct way to do it? Thanks.

+4  A: 

I believe this is what you are looking for =>Type.MakeGenericType

Arnis L.
+7  A: 

What' you're trying to do is not really possible in the C# (and CLR) version of generics. When specifying a generic parameter it must be either ...

  • A Concrete type in code
  • Another generic parameter

This information must be bound in the metadata of the assembly. There is no way to express a type name from string in metadata in this fashion.

It is possible to bind a generic at runtime based on string names but this requires reflection.

JaredPar
A: 

Here is a sample using reflection to load a generic type.

using System;
namespace GenericCastRuntime
{
    class Program
    {
        static void Main(string[] args)
        {
            string type = "GenericCastRuntime.Program+Provider`1";
            Type t = Type.GetType(type);

            string genericType = "System.String";
            Type gt = Type.GetType(genericType);

            var objType = t.MakeGenericType(gt);
            var ci = objType.GetConstructor(Type.EmptyTypes);
            var obj = ci.Invoke(null);
            IProvider provider = obj as IProvider;
        }

        public class Provider<T> : IProvider<T>
        {
            public T Value { get; set; }

            object IProvider.Value
            {
                get { return this.Value; }
                set
                {
                    if (!(value is T)) throw new InvalidCastException();
                    this.Value = (T)value;
                }
            }

        }

        public interface IProvider { object Value { get; set; } }
        public interface IProvider<T> : IProvider { T Value { get; set; } }
    }
}
Matthew Whited
A: 

Here's a simple example:

    public static object DynamicallyCreateGeneric(Type GenericTypeSource, Type SpecificTypeSource)
    {
        System.Type SpecificType = 
            GenericTypeSource.MakeGenericType(
            new System.Type[] { SpecificTypeSource }
            );

        return Activator.CreateInstance(SpecificType);
    }

...then, for example:

        string type = "System.String";
        Type t = Type.GetType(type);

        var DynamicallyCreatedGeneric = DynamicallyCreateGeneric(typeof(List<>), t);

        System.Diagnostics.Debugger.Break();

Adapt to suit your implementation and to taste. Of course, this method is not ideal. One of the best parts of generics is type compiler level type safety.

Robert Venables