In C# I have the following object:
public class Item
{ }
public class Task<T>
{ }
public class TaskA<T> : Task<T>
{ }
public class TaskB<T> : Task<T>
{ }
I want to dynamically create TaskA or TaskB using C# reflection (Activator.CreateInstance). However I wouldn't know the type before hand, so I need to dynamically create TaskA based on string like "namespace.TaskA" or "namespace.TaskAB".
This question is related to
c#
generics
reflection
activator
I know this question is resolved but, for the benefit of anyone else reading it; if you have all of the types involved as strings, you could do this as a one liner:
IYourInterface o = (Activator.CreateInstance(Type.GetType("Namespace.TaskA`1[OtherNamespace.TypeParam]") as IYourInterface);
Whenever I've done this kind of thing, I've had an interface which I wanted subsequent code to utilise, so I've casted the created instance to an interface.
Indeed you would not be able to write the last line.
But you probably don't want to create the object, just for the sake or creating it. You probably want to call some method on your newly created instance.
You'll then need something like an interface :
public interface ITask
{
void Process(object o);
}
public class Task<T> : ITask
{
void ITask.Process(object o)
{
if(o is T) // Just to be sure, and maybe throw an exception
Process(o as T);
}
public void Process(T o) { }
}
and call it with :
Type d1 = Type.GetType("TaskA"); //or "TaskB"
Type[] typeArgs = { typeof(Item) };
Type makeme = d1.MakeGenericType(typeArgs);
ITask task = Activator.CreateInstance(makeme) as ITask;
// This can be Item, or any type derived from Item
task.Process(new Item());
In any case, you won't be statically cast to a type you don't know beforehand ("makeme" in this case). ITask allows you to get to your target type.
If this is not what you want, you'll probably need to be a bit more specific in what you are trying to achieve with this.
Make sure you're doing this for a good reason, a simple function like the following would allow static typing and allows your IDE to do things like "Find References" and Refactor -> Rename.
public Task <T> factory (String name)
{
Task <T> result;
if (name.CompareTo ("A") == 0)
{
result = new TaskA ();
}
else if (name.CompareTo ("B") == 0)
{
result = new TaskB ();
}
return result;
}
It seems to me the last line of your example code should simply be:
Task<Item> itsMe = o as Task<Item>;
Or am I missing something?
Source: Stackoverflow.com