How to Pass Parameters to Activator.CreateInstance<T>()
Asked Answered
G

5

302

I want to create an instance of a type that I specify in a generic method that I have. This type has a number of overloaded constructors. I'd like to be able to pass arguments to the constructors, but

Activator.CreateInstance<T>()

doesn't see to have this as an option.

Is there another way to do it?

Giulia answered 16/3, 2010 at 0:7 Comment(1)
S
573

Yes.

(T)Activator.CreateInstance(typeof(T), param1, param2);
Surinam answered 16/3, 2010 at 0:8 Comment(1)
this is not correct, if your param1 is a bool this will fail because of learn.microsoft.com/en-us/dotnet/api/…Enhanced
M
37

There is another way to pass arguments to CreateInstance through named parameters.

Based on that, you can pass a array towards CreateInstance. This will allow you to have 0 or multiple arguments.

public T CreateInstance<T>(params object[] paramArray)
{
  return (T)Activator.CreateInstance(typeof(T), args:paramArray);
}
Miasma answered 22/9, 2016 at 4:6 Comment(0)
R
22

Edit: Since the post of this answer things have changed in .NET 7. see this article for performance improvements.

https://devblogs.microsoft.com/dotnet/performance_improvements_in_net_7/

Kudos to @balrob for the heads up in the comments.

Keep in mind though that passing arguments on Activator.CreateInstance has a significant performance difference versus parameterless creation.

There are better alternatives for dynamically creating objects using pre compiled lambda. Of course always performance is subjective and it clearly depends on each case if it's worth it or not.

Details about the issue on this article.

Graph is taken from the article and represents time taken in ms per 1000 calls.

Performance comparison

Rallentando answered 7/8, 2018 at 8:32 Comment(4)
For context, this chart means that (on average, on the same hardware) each invocation of a parameterized constructor with Activator.CreateInstance will take 0.0035ms (or 3.5 microseconds) - depending on your application this may not even register in performance-tests at all.Goldagoldarina
Ouch! Sometimes the old way is much better. Not going to be using Activators, for sure. That's pretty dismal performance!Eddra
The quoted article is from 2010 - and is most likely no longer applicable. CreateInstance() is called out in the performance notes for .net 7 as being significantly faster.Mabelmabelle
while it is faster, it still seems to be unreasonably slow for what it is... i just benchmarked it with .NET 7 and 8Branscum
F
6

As an alternative to Activator.CreateInstance, FastObjectFactory in the linked url preforms better than Activator (as of .NET 4.0 and significantly better than .NET 3.5. No tests/stats done with .NET 4.5). See StackOverflow post for stats, info and code:

How to pass ctor args in Activator.CreateInstance or use IL?

Fluoresce answered 17/6, 2010 at 3:19 Comment(2)
Do you mean that there is an alternative solution (linked) which is likely to perform better than Activator.CreateInstance when you are passing parameters? Or that is likely to perform better in all cases?Speculation
I haven't done performance tests in a while and it looks like someone posted .NET 4.0 stats, but yes with .NET 4.0 it looks like FastObjectFactory has better performance. Activator.CreateInstance was horrible in .NET 3.5 and was significantly faster in .NET 4.0 however still slower than FastObjectFactory linked in that url.Fluoresce
H
-3
public class AssemblyLoader<T>  where T:class
{
    public void(){
        var res = Load(@"C:\test\paquete.uno.dos.test.dll", "paquete.uno.dos.clasetest.dll") 
    }

    public T Load(string assemblyFile, string objectToInstantiate) 
    {
        var loaded = Activator.CreateInstanceFrom(assemblyFile, objectToInstantiate).Unwrap();

        return loaded as T;
    }
}
Hearsh answered 3/4, 2020 at 20:13 Comment(1)
This is unexplained code-only. I doubt that it helps or even works at all. To convince me otherwise please explain how this works and why it is supposed to solve the problem.Outrange

© 2022 - 2024 — McMap. All rights reserved.