none
c# - declaring an object type based on a string RRS feed

  • Question

  • I have an object that can be one of several classes (eg clsA, clsB, etc).  I would like to declare the object based on a string (which is contained in a database).

    I have tried using CreateInstance:

    object obj1

    obj1 = Activator.CreateInstance(null, "WindowsFormsApplication1.clsA");

    However, even though the Createinstance method appeared to work correctly, I cannot reference obj1.  In the debugger, I get the message "the name obj1 does not exist in the current context".  Any help would be appreciated.

    Monday, October 15, 2012 6:05 PM

Answers

  • You should be able to use:

    object obj1 = Activator.CreateInstance(Type.GetType("WindowsFormsApplication1.clsA"));

    That will give the proper resulting type.

    The overload you're using returns an ObjectHandle (see http://msdn.microsoft.com/en-us/library/d133hta4.aspx) which would have to be unwrapped to get the actual object.


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Monday, October 15, 2012 10:46 PM
    Moderator
  • You should be able to reference this - but you would need to use reflection to get the properties and values, etc, since you only have an object:

    object obj1 = Activator.CreateInstance(null, "WindowsFormsApplication1.clsA");
    
    Type theType = obj1.GetType(); // Should be typeof(clsA)
    var properties = theType.GetProperties();
    
    //...


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by simb11 Tuesday, October 16, 2012 4:15 PM
    Monday, October 15, 2012 6:14 PM
    Moderator

All replies

  • You should be able to reference this - but you would need to use reflection to get the properties and values, etc, since you only have an object:

    object obj1 = Activator.CreateInstance(null, "WindowsFormsApplication1.clsA");
    
    Type theType = obj1.GetType(); // Should be typeof(clsA)
    var properties = theType.GetProperties();
    
    //...


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by simb11 Tuesday, October 16, 2012 4:15 PM
    Monday, October 15, 2012 6:14 PM
    Moderator
  • Thanks, Reed.  I'll play around with that and get back to you....
    Monday, October 15, 2012 6:31 PM
  • Hi,

    I feel like we're on the right track, but still not there yet.

    After executing the code Type theType = obj1.GetType(), theType is of type ObjectHandle, not ClsA.  The properties variable is empty.

    The code seems to work when I put the class into the Type.GetType() statement - ie Type.GetType("WindowsFormsApplication1.clsA"), but the how would I create the object and assign values to the properties?

    Thanks again.

    Monday, October 15, 2012 10:20 PM
  • You should be able to use:

    object obj1 = Activator.CreateInstance(Type.GetType("WindowsFormsApplication1.clsA"));

    That will give the proper resulting type.

    The overload you're using returns an ObjectHandle (see http://msdn.microsoft.com/en-us/library/d133hta4.aspx) which would have to be unwrapped to get the actual object.


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Monday, October 15, 2012 10:46 PM
    Moderator
  • That did it.

    Thanks for your help, Reed

    Monday, October 15, 2012 10:53 PM
  • simb11,

    In general, please mark the answer that helped you and solved your issue as the answer, not your own response.

    Thank you.


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Monday, October 15, 2012 11:44 PM
    Moderator
  • Oops - sorry.  That's what I intended to do.  Thanks once again, Reed
    Monday, October 15, 2012 11:45 PM
  • For anyone that may be looking for a similar solution, here is my final working solution to create an object, assign a value to a property in that object, and call a method, all using reflection:

    Given a class with a property and a method:

    class clsA {

     String someProperty {get;set;}

     void SomeMethod ()

    { my code }

    }

    // create the object

    object obj1 = Activator.CreateInstance(Type.GetType("namespace.clsA"));

    //Assign a value to property someProperty

    PropertyInfo prpSomeProperty = obj1.GetType().GetProperty("someProperty");

    prpSomeProperty.SetValue(obj1,"value to assign",null);

    //Call method someMethod

    MethodInfo mi = obj1.GetType().GetMethod("someMethod");

    mi.Invoke(obj1,null);

    Good luck!


    • Edited by simb11 Tuesday, October 16, 2012 4:35 PM
    Tuesday, October 16, 2012 4:11 PM
  • BTW - If your three classes (clsA, clsB, clsC) all implement a common interface, you can simplify this.  For example, if the SomeProperty and SomeMethod were part of "IYourInterface", you could always do:

    object obj1 = Activator.CreateInstance(Type.GetType("namespace.clsA"));
    
    IYourInterface objInterface = obj1 as IYourInterface;
    
    if (objInterface == null)
    {
        // Handle error case - shouldn't happen if the class implements the interface
    }
    
    // Just call these directly
    objInterface.SomeProperty = "foo";
    objInterface.SomeMethod();

    Often, when dealing with dynamically loaded/created types, this is a better and cleaner approach than using reflection for the entire thing.

    That being said, there's also another option using C# 4's dynamic - using runtime binding:

    // Declare this dynamic!
    dynamic obj1 = Activator.CreateInstance(Type.GetType("namespace.clsA"));
    
    // Just use it directly now:
    obj1.SomeProperty = "Foo";
    obj1.SomeMethod();
    

    Just thought I"d include it for more info. ;)


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    Tuesday, October 16, 2012 4:26 PM
    Moderator
  • Just an update - I changed my program to use the method you suggested (using an interface).  It works like a charm.  Thanks again for your help, Reed.
    Wednesday, November 7, 2012 10:03 PM