This question already has answers here:
Closed 6 years ago.
What's the best way (in .NET 4) to create an instance of a type determined at runtime.
I have an instance method which although acting on a BaseClass object may be called by instances of its derived classes. I require to create another instance of the same type as this
within the method. Overloading the Method for each derived class is not practical as it is fairly involved and would be more efficient to keep to the single implementation.
public class BaseClass
{
//constructors + properties + methods etc
public SomeMethod()
{
//some code
DerivedClass d = new DerivedClass(); //ideally determine the DerivedClass type at run-time
}
}
I've read a bit about reflection or using the dynamic keyword but i don't have experience with these.
You are looking for Activator.CreateInstance
(there are also other overloads, such as this one that accepts constructor arguments). So you could write
var anotherOneLikeMe = Activator.CreateInstance(this.GetType());
There may be a problem here in that anotherOneLikeMe
is going to be typed as object
, so unless you intend to cast it to a common base class (e.g. BaseClass
in your example) there's not much that you can do with it.
Best way for performance to repeatedly create instance in runtime is compiled expression:
static readonly Func<X> YCreator = Expression.Lambda<Func<X>>(
Expression.New(typeof(Y).GetConstructor(Type.EmptyTypes))
).Compile();
X x = YCreator();
Statistics (2012):
Iterations: 5000000
00:00:00.8481762, Activator.CreateInstance(string, string)
00:00:00.8416930, Activator.CreateInstance(type)
00:00:06.6236752, ConstructorInfo.Invoke
00:00:00.1776255, Compiled expression
00:00:00.0462197, new
Statistics (2015, .net 4.5, x64):
Iterations: 5000000
00:00:00.2659981, Activator.CreateInstance(string, string)
00:00:00.2603770, Activator.CreateInstance(type)
00:00:00.7478936, ConstructorInfo.Invoke
00:00:00.0700757, Compiled expression
00:00:00.0286710, new
Statistics (2015, .net 4.5, x86):
Iterations: 5000000
00:00:00.3541501, Activator.CreateInstance(string, string)
00:00:00.3686861, Activator.CreateInstance(type)
00:00:00.9492354, ConstructorInfo.Invoke
00:00:00.0719072, Compiled expression
00:00:00.0229387, new
Full code:
public static X CreateY_New()
{
return new Y();
}
public static X CreateY_CreateInstance()
{
return (X)Activator.CreateInstance(typeof(Y));
}
public static X CreateY_CreateInstance_String()
{
return (X)Activator.CreateInstance("Program", "Y").Unwrap();
}
static readonly System.Reflection.ConstructorInfo YConstructor =
typeof(Y).GetConstructor(Type.EmptyTypes);
static readonly object[] Empty = new object[] { };
public static X CreateY_Invoke()
{
return (X)YConstructor.Invoke(Empty);
}
static readonly Func<X> YCreator = Expression.Lambda<Func<X>>(
Expression.New(typeof(Y).GetConstructor(Type.EmptyTypes))
).Compile();
public static X CreateY_CompiledExpression()
{
return YCreator();
}
static void Main(string[] args)
{
const int iterations = 5000000;
Console.WriteLine("Iterations: {0}", iterations);
foreach (var creatorInfo in new []
{
new {Name = "Activator.CreateInstance(string, string)", Creator = (Func<X>)CreateY_CreateInstance},
new {Name = "Activator.CreateInstance(type)", Creator = (Func<X>)CreateY_CreateInstance},
new {Name = "ConstructorInfo.Invoke", Creator = (Func<X>)CreateY_Invoke},
new {Name = "Compiled expression", Creator = (Func<X>)CreateY_CompiledExpression},
new {Name = "new", Creator = (Func<X>)CreateY_New},
})
{
var creator = creatorInfo.Creator;
var sum = 0;
for (var i = 0; i < 1000; i++)
sum += creator().Z;
var stopwatch = new Stopwatch();
stopwatch.Start();
for (var i = 0; i < iterations; ++i)
{
var x = creator();
sum += x.Z;
}
stopwatch.Stop();
Console.WriteLine("{0}, {1}", stopwatch.Elapsed, creatorInfo.Name);
}
}
public class X
{
public X() { }
public X(int z) { this.Z = z; }
public int Z;
}
public class Y : X { }
I know this was marked as reflection, but I generally see reflection as a last resort for performance and complexity reasons. There are some instances where your design/usage requires reflection; however, I'll offer some alternatives for consideration:
Use a factory Func
:
public void SomeMethod(Func<BaseClass> createDerived)
{
BaseClass d = createDerived();
}
Make your method use a constrained generic type:
public void SomeMethod<TDerived>() where TDerived : BaseClass, new()
{
TDerived d = new TDerived();
}
Under the covers this last alternative makes use of Activator.CreateInstance
as others have suggested. I prefer the last to reflection because they both require a parameter-less constructor, but the compiler enforces the constraint that the derived type must have a parameterless constructor whereas the reflection approach results in a runtime exception.
The problem here is you can never know the type of DerivedClass
at compile time.
You can however do this type of thing:
BaseClass obj = new DerivedClass();
This is implemented like this:
BaseClass obj = (BaseClass)Activator.CreateInstance(this.GetType());
This call will fail if the DerivedClass has no parameterless constructors though.
This really depends on what you mean by "runtime" and what the goals are. For example, Jon and Bas have both hit on the idea of using Reflection to late bind a particular class and have it instantiated at Runtime. This is certainly one idea and you can even discover the methods on the object at runtime, if that is your goal
If you are using interfaces, you have a couple of additional options. The Microsoft Extensibility Framework (or MEF) might be an option you want to look at, as it includes discoverability and instantiation at runtime. The downside is the discovered class must adhere to the correct interface, but this is not a real issue in most cases.
If you know the classes you are loading, and they have the same interface (common theme), but want to instantiate different classes at runtime, IoC containers are an option. This is not particularly what you are asking about.
The dynamic keyword is not what you are looking for. It does load at runtime, but the dyanmic is more about the compiler not checking if the methods you are calling actually exist. Done incorrectly, you can end up with an interesting blowup when you call a method that does not exist. The main motivation I have seen for dyanamic is interaction with a dynamic language, like IronPython.
public void SomeMethod()
{
object x =Activator.CreateInstance(this.GetType());
}
This should create a new instance, on the other hand I wonder the why you trying to do this.
While indeed you need to use Activator.CreateInstance you might wanna look specifically into the Activator.CreateInstance(String, String) which can be invoked using the name of the class which you might know during runtime.
This will be mostly beneficial if you are instantiating Derived Types on the Base Type. If you're going to be calling SomeMethod
from the derived type itself then the previous answers using this.GetType()
should be sufficient.