C# How to Initialize Generic class with object of type "Type"
Solution 1
You want Type.MakeGenericType
and then Activator.CreateInstance
... but then calling a method on the newly-created object will be tricky. Ideally you could have a non-generic base class or interface containing those members:
public interface IFoo
{
void CallSomeMethod();
}
public class MyGenericClass<T> : IFoo
{
...
}
// Names changed to be more conventional
public void DoSomething(Type type)
{
var genericType = typeof(MyGenericClass<>).MakeGenericType(type);
var instance = (IFoo) Activator.CreateInstance(genericType);
instance.CallSomeMethod();
}
If you do need to call a method which depends on the type parameter, you'll need to do that with reflection, or with dynamic
which can streamline reflection-based code.
EDIT: As cdhowie says, if you always actually do know the type at compile-time, you can use a generic method which would make things much simpler. You'd then call the method like this:
DoSomething<int>();
DoSomething<MyClassA>();
DoSomething<MyClassB>();
Solution 2
Like this:
object myGenObj = Activator.CreateInstance(typeof(MyGenericClass<>).MakeGenericType(_type));
However, since the produced object is of a type that you don't know at compile-time, you can't really invoke members of the object through the generic type (except via reflection). If there is an ancestor type or implemented interface that you do know of at compile-time, you can cast to that and then invoke the member.
You might also consider wrapping this functionality in a generic method, which makes the whole thing easier to deal with:
public void doSomething<T>()
{
var myGenObj = new MyGenericClass<T>();
myGenObj.doSomeGenStuff();
}
If you have to support Type
objects you can use an overload that cheats using reflection:
public void doSomething(Type _type)
{
this.GetType().GetMethod("doSomething", Type.EmptyTypes)
.MakeGenericMethod(_type)
.Invoke(this, null);
}
RayLoveless
Software Engineer in the beautiful state of Utah. Happy trails :). If you want to contact me I use my stack overflow username @gmail.com.
Updated on July 26, 2022Comments
-
RayLoveless almost 2 years
I recently had this problem.
doSomething(typeof(int)); doSomething(typeof(MyClassA)); doSomething(typeof(MyClassB)); public void doSomething(Type _type) { var myGenObj = new MyGenericClass<_type>(); // Error. Really I'd want MyGenericClass<int>, MyGenericClass<MyClassA>, etc depending on what's passed in. myGenObj.doSomeGenStuff(); // more stuff... }
I think that this can be done with reflection somehow.. Possibly there's an easier way. I've been somewhat confused on how Type works vs Classes under the covers. Anyways thanks for any help.
Thanks.
-
RayLoveless over 10 yearsThanks, Thought there was a cleaner solution but I guess not.
-
Jon Skeet over 10 years@RayL: No, generics are tricky with reflection - they're basically designed for when the type arguments are known at compile-time.
-
RayLoveless over 10 yearsThanks, Wasn't sure who to mark as answer on this one but people seemed to like skeets answer a bit more. Sorry you had to compete with him :)
-
Jon Skeet over 10 years@RayL: Read cdhowie's answer as well - all the samples you've given are where the type argument is known at compile-time. Is that actually the case? If so, use a generic method.