views:

8272

answers:

9

One may not always know the Type of an object at compile-time, but may need to create an instance of the Type. How do you get a new object instance from a Type?

+1  A: 

One implementation of this problem is to attempt to call the parameter-less constructor of the Type:

    public static object GetNewObject(Type t)
{
try
{
return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
}
catch
{
return null;
}
}

Here is the same approach, contained in a generic method:

    public static T GetNewObject<T>()
{
try
{
return (T)typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { });
}
catch
{
return default(T);
}
}
tags2k
+25  A: 

The Activator class within the root System namespace is pretty powerful.

There are a lot of overloads for passing parameters to the constructor and such. Check out the documentation at: http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx

Here are some simple examples:

ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);

ObjectType instance = (ObjectType)Activator.CreateInstance("MyNamespace.ObjectType, MyAssembly");

Karl Seguin
Exactly! Thanks Karl!
Fabio Milheiro
A: 

-1 to tags2k for swollowing exceptions, and to all of you who marked him up...tsktsk

Karl Seguin
A: 

My apologies, I keep this code in my Utils class and I felt that it wasn't the place of this method to be doing anything other than its best to get you an object. If the issue is that the class is throwing an exception on instantiation, this will also be thrown when default(T) is called, but if the problem is that the constructor does not exist you will get null. If you are using the non-generic version you will get null regardless.

One would expect an object back from GetNewObject, so a null check should suffice in tracking down the problem.

tags2k
A: 

tags2k:

If the issue is that the class is throwing an exception on instantiation, this will also be thrown when default(T) is called

This is not true. default() does not call constructors, it initializes to null for reference types (classes), 0 for value types (eg. ints), and initializes each member of a struct to one of null or 0, based on the same rules.

Ch00k
A: 

If this is for something that will be called a lot in an application instance, it's a lot faster to compile and cache dynamic code instead of using the activator or ConstructorInfo.Invoke(). Two easy options for dynamic compilation are compiled Linq Expressions or some simple IL opcodes and DynamicMethod. Either way, the difference is huge when you start getting into tight loops or multiple calls.

Thomas G. Mayfield
+8  A: 
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);

The Activator class has a generic variant that makes this a bit easier:

  ObjectType instance = Activator.CreateInstance<ObjectType>();
Konrad Rudolph
A: 

-1 to tags2k for swallowing exceptions, and to all of you who marked him up...tsktsk

Ditto, except I can't vote. stupid quota

Orion Edwards
+1  A: 

Wouldnt the generic "new T();" work?

boomhauer
Actually, it would in a generic class/method, but not for a given "Type".
boomhauer