Reputation: 237
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.
Upvotes: 4
Views: 2555
Reputation: 5981
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.
Upvotes: 0
Reputation: 22433
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; } }
}
}
Upvotes: 1
Reputation: 754615
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 ...
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.
Upvotes: 8
Reputation: 47567
I believe this is what you are looking for =>Type.MakeGenericType
Upvotes: 4