locked
How to New a class dynamically

    Question

  • Hi:
        In Java, I can use class.forName() to New a particular class(depend on the variable I assigned ) that I wanted.
        In .Net, how can I do such a function?
        Please give me some hits. Thanks a lot.
    Thursday, August 14, 2008 5:54 AM

Answers

  • If the class has a void constructor you can use Activator.CreateInstance. 

    If your class has parameters then you can use reflection to find the appropriate constructor and then invoke that.

    Hope this helps,

    David
    Thursday, August 14, 2008 6:59 AM
  • Crating and/or manipulating aribtrary objects based on constraints is *exactly* what generics is for; using it as a factory is just a specific (albeit unlikely) use-case. If you can show the flaw I'd love to see it...

    Re Activator.CreateInstance, yes - and I stated as much; I was merely presenting a perfectly valid alternative. In many cases, dynamic type creation is for things like plugins / dependency-injection, in which case it is likely that the type created conforms to some common interface etc, making the generics approach even more applicable. I didn't say "use generics" - I merely presented it as an option for consideration.

    Re your claim that "which can yield significant performance improvements" is flawed, care to elaborate? Simply: generic instantiation is twice as fast as Activator.CreateInstance (code below); I did qualify with "if you are doing something repeatedly" - for example, I have recently done a lot of work on high performance custom binary serialization, and reflection is simply much slower.

    Re "everybody talks about reflection and we cannot turn our back on it", I didn't suggest you did! In fact, MakeGenericMethod() etc *is* reflection. At the same time, reflection is known to be significantly slower than pretty-much any other approach. It is reasonable to know which tools are available for use, so you can pick the right tool for the job. For light use reflection may be fine, but not always. Note also that reflection is very limited on some frameworks such as Silverlight and CF.

    The generic approach becomes even more valuable when you have composite types to consider - for example, you know that they are talking about "some kind of collection [that you need to know] of some kind of object [that you need to know]" - this is very hard to do (while retaining sanity) via reflection, but via generics you can do:

    SomeGenericWossit<TList, TValue>(...) where TList : IList<TValue>
    (optionally perhaps with TList : new() and/or TValue : new())

    Which is a very expressive way of working with the list and values without having to use reflection everywhere.

    So yes: Activator.CreateInstance may be (depending on the full scenario, which we simply don't know) n entirely appropriate approach. But don't dismiss generics; unless you care to qualify your FUD.

    Performance test (ms):
    With Activator: 11719
    With generics: 6963


    using System;  
    using System.Diagnostics;  
    class Foo { }  
    static class Program  
    {  
        static void Main()  
        {  
            Type type = typeof(Foo);  
            const int count = 5000000;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            RunTestWithActivator(type, count);
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            typeof(Program).GetMethod("RunTestWithGenerics").  
                MakeGenericMethod(type).Invoke(nullnew object[] { count });  
        }  
        public static void RunTestWithActivator(Type type, int count)  
        {  
            Stopwatch watch = Stopwatch.StartNew();  
            for (int i = 0; i < count; i++)  
            {  
                object obj = Activator.CreateInstance(type);  
            }  
            watch.Stop();  
            Console.WriteLine("With Activator: {0}", watch.ElapsedMilliseconds);  
        }  
        public static void RunTestWithGenerics<T>(int count) where T : new() {  
            Stopwatch watch = Stopwatch.StartNew();  
            for (int i = 0; i < count; i++)  
            {  
                T t = new T();  
            }  
            watch.Stop();  
            Console.WriteLine("With generics: {0}", watch.ElapsedMilliseconds);  
        }  


     


    Marc
    Thursday, August 14, 2008 8:50 AM
  • Let us try not to go beyond the scope of the question, of course i understand you are giving an alternative to creating a dynamic object.

    if i may understand the question clearly, the type to be loaded dynamically is known, and i do not see where generics comes into play here. Generics is usefull in its own contex, but not in this scenairo.

    The question is the most likely equivalent of class.forName from Java to C# dynamic class loading. And i do not see where your approach comes in to solve the problem.

    "In many cases, dynamic type creation is for things like plugins / dependency-injection" still Generics does not answer this.


    @salakoahmed
    Thursday, August 14, 2008 9:05 AM

All replies

  • If the class has a void constructor you can use Activator.CreateInstance. 

    If your class has parameters then you can use reflection to find the appropriate constructor and then invoke that.

    Hope this helps,

    David
    Thursday, August 14, 2008 6:59 AM
  • Activator.CreateInstance (or other reflection) is one approach; another is generics; perhaps use a generic method / generic type from your code with the new() constraint - for example:

    public class Factory<T> where T : new() {
      T Create() {return new T();}
    }

    There are more elegant ways of using this, of course - but the main point is that you can use the new() generic constraint to enforce access only to types that have a public parameterless constructor. This is handy in libraries where the type is going to be provided by the caller - for example:

    public clas MyList<T> : List<T> where T : new() {
      public T AddNew() {
        T t = new T();
        Add(t);
        return t;    
      }
    }

    The library code cannot know about the T that is going to be used by the caller, but when the user does

    MyList<Foo> list = new MyList<Foo>();

    your library code gets the ability to create new Foo instances; and if the Foo in question doesn't have a public parameterless constructor, then the caller knows at compile time that they can't use MyList<T>.
    Marc
    • Edited by Marc GravellMVP Thursday, August 14, 2008 7:09 AM clarified generic types
    Thursday, August 14, 2008 7:07 AM
  • That's true although I understood the original poster's question to mean they only had a string value for the type required; and so a solution using generics wouldn't add much value.

    A better question would be: why are you trying to create types from a typename string anyway?  And I suspect the answer to that may well result in a pattern that would look quite like Marc's.

    _
    D
    Thursday, August 14, 2008 7:13 AM
  • Well, it wasn't clear whether it was a string, a Type, or just an arbitrary variable ;-p

    Note that in such cases you can also use MakeGenericMethod() / MakeGenericType() to switch into a generic context (rather than using reflection constantly), which can yield significant performance improvements if you are doing something repeatedly. But as always the nature of the specific problem (which we don't [yet] know) makes a difference...
    Marc
    Thursday, August 14, 2008 7:54 AM
  • First of all, the usage of Generics is not to dynamically create an object at runtime.
    The proposed solution is flawed and its not what Sid.Feng asked for.

    If i may get him very well, the Class.forName in java is equivalent to the Activator.CreateInstance or Assemby.CreateInstance, all which are overloaded to create a parameterless and constructor that takes argument.

    The question is straight forward and i wont have imagine someone trying to plumb using a generics approach.

    The equivalent to class.forName is Activator.CreatInstance, Assembly.CreateInstance etc...

    Also, this statement : "which can yield significant performance improvements", is flawed, everybody talks about reflection and we cannot turn our back on it.

    You can do the following :

    Activator.CreateInstance(Type.GetType("ClassName"));

    You can use the class fully qualified name if you want.


    Cheers and Enjoy.


    @salakoahmed
    Thursday, August 14, 2008 8:21 AM
  • Crating and/or manipulating aribtrary objects based on constraints is *exactly* what generics is for; using it as a factory is just a specific (albeit unlikely) use-case. If you can show the flaw I'd love to see it...

    Re Activator.CreateInstance, yes - and I stated as much; I was merely presenting a perfectly valid alternative. In many cases, dynamic type creation is for things like plugins / dependency-injection, in which case it is likely that the type created conforms to some common interface etc, making the generics approach even more applicable. I didn't say "use generics" - I merely presented it as an option for consideration.

    Re your claim that "which can yield significant performance improvements" is flawed, care to elaborate? Simply: generic instantiation is twice as fast as Activator.CreateInstance (code below); I did qualify with "if you are doing something repeatedly" - for example, I have recently done a lot of work on high performance custom binary serialization, and reflection is simply much slower.

    Re "everybody talks about reflection and we cannot turn our back on it", I didn't suggest you did! In fact, MakeGenericMethod() etc *is* reflection. At the same time, reflection is known to be significantly slower than pretty-much any other approach. It is reasonable to know which tools are available for use, so you can pick the right tool for the job. For light use reflection may be fine, but not always. Note also that reflection is very limited on some frameworks such as Silverlight and CF.

    The generic approach becomes even more valuable when you have composite types to consider - for example, you know that they are talking about "some kind of collection [that you need to know] of some kind of object [that you need to know]" - this is very hard to do (while retaining sanity) via reflection, but via generics you can do:

    SomeGenericWossit<TList, TValue>(...) where TList : IList<TValue>
    (optionally perhaps with TList : new() and/or TValue : new())

    Which is a very expressive way of working with the list and values without having to use reflection everywhere.

    So yes: Activator.CreateInstance may be (depending on the full scenario, which we simply don't know) n entirely appropriate approach. But don't dismiss generics; unless you care to qualify your FUD.

    Performance test (ms):
    With Activator: 11719
    With generics: 6963


    using System;  
    using System.Diagnostics;  
    class Foo { }  
    static class Program  
    {  
        static void Main()  
        {  
            Type type = typeof(Foo);  
            const int count = 5000000;
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            RunTestWithActivator(type, count);
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            typeof(Program).GetMethod("RunTestWithGenerics").  
                MakeGenericMethod(type).Invoke(nullnew object[] { count });  
        }  
        public static void RunTestWithActivator(Type type, int count)  
        {  
            Stopwatch watch = Stopwatch.StartNew();  
            for (int i = 0; i < count; i++)  
            {  
                object obj = Activator.CreateInstance(type);  
            }  
            watch.Stop();  
            Console.WriteLine("With Activator: {0}", watch.ElapsedMilliseconds);  
        }  
        public static void RunTestWithGenerics<T>(int count) where T : new() {  
            Stopwatch watch = Stopwatch.StartNew();  
            for (int i = 0; i < count; i++)  
            {  
                T t = new T();  
            }  
            watch.Stop();  
            Console.WriteLine("With generics: {0}", watch.ElapsedMilliseconds);  
        }  


     


    Marc
    Thursday, August 14, 2008 8:50 AM
  • Let us try not to go beyond the scope of the question, of course i understand you are giving an alternative to creating a dynamic object.

    if i may understand the question clearly, the type to be loaded dynamically is known, and i do not see where generics comes into play here. Generics is usefull in its own contex, but not in this scenairo.

    The question is the most likely equivalent of class.forName from Java to C# dynamic class loading. And i do not see where your approach comes in to solve the problem.

    "In many cases, dynamic type creation is for things like plugins / dependency-injection" still Generics does not answer this.


    @salakoahmed
    Thursday, August 14, 2008 9:05 AM
  •  
    Hi Marc

    I'm still new to reflection and have a small query regarding your solution.

    At run time I need to compile a [unknown] class file depending on what component and version number that was supplied by the calling application.
    How would I not use reflection but instead use the generic option you mentioned above?

    Guess what I'm looking for is a bit of direction on how to solve this problem; 1) use reflection to compile the class object and then utilise that class.  2)  call the generic factory passing in the name and version #.

    Thursday, October 2, 2008 2:52 PM
  • The generic option also uses reflection - it just does it once rather than lots. Either should be fine - so if you have something working, stick with it ;-p

    If you are compiling at runtime you'll just need to load the Assembly from disk and use Assembly.GetType(name). If you are using Reflection.Emit you will get the Type directly when finishing construction.

    Marc
    Thursday, October 2, 2008 8:46 PM