locked
Instantiate an object from in interface class..... RRS feed

  • Question

  • Im fairly new to classes objects etc... ( as you can see from my title above ! ) and wondered if you could resolve an issue for me

    Ive got an simple interface :

    public

     

    interface IFileClass {string FileName { get; set; } string FileLocation { get; set; }}

    And a simple class that inherits the above interface :

    public

     

    class MyFileClass : IFileClass{

     

    private string _filename = ""; private string _filelocation = "";

     

     

    public string FileLocation

    {

     

    get { return _filelocation; }

     

    set { _filelocation = value; }

    }

     

    public string FileName

    {

     

    get { return _filename; }

     

    set { _filename = value; }

    }

     

    }

    im then parsing the MyFileClass into another class via the IFileClass interface :

    public

     

    ReadFiles(IFileList fileclass, string filelocation)

    {

    _fileclass = fileclass;

    _fileslocation = filelocation;

     

    this.GetFileList();

     

    }

    }

    OK, what i want to do is this.  I want to instantiate whatever the type of IFileClass is parsed.  So in the case, MyFileClass is parsed through IFileClass fileclass and i want to find out at runtime what fileclass is.  And then instantiate that object. 


    I cant obviously instantiate a interface, but if i get the object type, i could instantiate that ? 

    any help would be appreciated

    Monday, July 6, 2009 2:56 PM

Answers

  • Sure, just create a switch or a series of if statements that determine what to set "t" to.  I'm not sure I completely understand what the issue is here. 

    Type t;

    if (blah blah blah)
    {
         t = typeof(MySecondFileClass);
    }
    else if (blah blah blue)
    {
        t = typeof(MyFileClass);
    }
    else
    {
        t = typeof(MyLastFileClass);
    }
    ......

    IFileClass instance = (IFileClass)Activator.CreateInstance(t);

    // if all the types that could be set to "t" are 
    // implementing IFileClass, then this should work just fine.
    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    • Marked as answer by liurong luo Tuesday, July 7, 2009 9:53 AM
    Monday, July 6, 2009 3:17 PM
  • Personally, from the sounds of it, I would make a little bit of a change to your system, and use Generics to allow this, it makes for nice clean code.

    You can simply do this.

    public ReadFiles<T> (T myInputObject) where T : IFileClass
    {
        T myObject;
        //Instantiate
        myObject = Activator.CreateInstance<T>();
    }

    This still forces type safety, but keeps the code nice and simple.  The key here is the where T : IFileClass part, which restricts the method to only accept object that implement that interface.
    Mitchel Sellers, MCITP, MCPD, MCTS - http://www.mitchelsellers.com
    • Proposed as answer by wheaties Monday, July 6, 2009 3:35 PM
    • Marked as answer by liurong luo Tuesday, July 7, 2009 9:53 AM
    Monday, July 6, 2009 3:29 PM

All replies

  • If you get the type at runtime, you can.  Just do something like this:

    Type t = typeof(FileClass);  // instantiate "t" to whatever type you need.

    IFileClass value = (IFileClass)Activator.CreateInstance(t);
    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    Monday, July 6, 2009 3:00 PM
  • thanks for your quick response

    i get the following message when i tried the above

    The type or namespace name 'fileclass' could not be found (are you missing a using directive or an assembly reference?)

    but fileclass is parsed in :

    public

     

    ReadFiles(IFileList fileclass, string filelocation)


    is there anything else i can try ?

    Monday, July 6, 2009 3:07 PM
  • You have to use the name of the class you've created instead.  In the example above, I was calling the inherited class "FileClass".  Looks like in your implementation, it might be "MyFileClass" instead, so you would do something like:

    Type t = typeof(MyFileClass);
    IFileClass value = Activator.CreateInstance(t);

    If the class you create from inheriting from IFileClass changes to another name, you'll have to replace the name of that new class with MyFileClass.  More than that, if you have only one implementation, then you should just call the "new" keyword on the only implementation you have, as "determining at runtime" makes no difference if that's the case.

    IFileClass value = new MyFileClass();
    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    Monday, July 6, 2009 3:10 PM

  • I see now.  But, what i was trying to do is at runtime allow ANY class that inherits from the IFileClass interface to be parsed in, instantiate the object and then add it to an arraylist of objects

    I want the class that does this to not know anything about the class thats being parsed in and i thought as long as it inherits from the IFileClass interface, that this would be possible

    But is this possible or not ?  it sounds like its not....
    Monday, July 6, 2009 3:14 PM
  • Sure, just create a switch or a series of if statements that determine what to set "t" to.  I'm not sure I completely understand what the issue is here. 

    Type t;

    if (blah blah blah)
    {
         t = typeof(MySecondFileClass);
    }
    else if (blah blah blue)
    {
        t = typeof(MyFileClass);
    }
    else
    {
        t = typeof(MyLastFileClass);
    }
    ......

    IFileClass instance = (IFileClass)Activator.CreateInstance(t);

    // if all the types that could be set to "t" are 
    // implementing IFileClass, then this should work just fine.
    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    • Marked as answer by liurong luo Tuesday, July 7, 2009 9:53 AM
    Monday, July 6, 2009 3:17 PM
  • I thought as much, but then this hard coded and so the class knows whats going to be parsed in.

    Never mind, thanks for your help though, its very much appreciated
    Monday, July 6, 2009 3:21 PM
  • David is right at some point you have to instantiate the actual named object. Once that is done you can cast a reference to the interface and work off of that as normal.
    William Wegerson (www.OmegaCoder.Com)
    Monday, July 6, 2009 3:22 PM
  • I thought as much, but then this hard coded and so the class knows whats going to be parsed in.

    Never mind, thanks for your help though, its very much appreciated

    Yeah, at some point, you've got to hard code your class types somewhere in order to determine which should be used.  Implementing Factory Pattern is always this way.
    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    Monday, July 6, 2009 3:23 PM
  • I see, thanks again
    Monday, July 6, 2009 3:23 PM
  • David is right at some point you have to instantiate the actual named object. Once that is done you can cast a reference to the interface and work off of that as normal.
    William Wegerson (www.OmegaCoder.Com)

    Bill,

    Just noticed the shiny "MVP" tag.  Were you just awarded the MVP award as well?  If so, congrats!  Very well deserved, and in my opinion, way overdue. 

    -David
    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    Monday, July 6, 2009 3:28 PM
  • Personally, from the sounds of it, I would make a little bit of a change to your system, and use Generics to allow this, it makes for nice clean code.

    You can simply do this.

    public ReadFiles<T> (T myInputObject) where T : IFileClass
    {
        T myObject;
        //Instantiate
        myObject = Activator.CreateInstance<T>();
    }

    This still forces type safety, but keeps the code nice and simple.  The key here is the where T : IFileClass part, which restricts the method to only accept object that implement that interface.
    Mitchel Sellers, MCITP, MCPD, MCTS - http://www.mitchelsellers.com
    • Proposed as answer by wheaties Monday, July 6, 2009 3:35 PM
    • Marked as answer by liurong luo Tuesday, July 7, 2009 9:53 AM
    Monday, July 6, 2009 3:29 PM
  • Personally, from the sounds of it, I would make a little bit of a change to your system, and use Generics to allow this, it makes for nice clean code.

    You can simply do this.

    public ReadFiles<T> (T myInputObject) where T : IFileClass
    
    {
    
        T myObject;
    
        //Instantiate
    
        myObject = Activator.CreateInstance<T>();
    
    }
    
    

    This still forces type safety, but keeps the code nice and simple.  The key here is the where T : IFileClass part, which restricts the method to only accept object that implement that interface.
    Mitchel Sellers, MCITP, MCPD, MCTS - http://www.mitchelsellers.com

    Or you could eliminate the Activator, and restrict T to new();

    public ReadFiles<T> (T myInputObject) where T : IFileClass, new()
    {
        IFileClass myObject = new T();
    }

    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    Monday, July 6, 2009 3:32 PM
  • Thats very interesting.... will look into it, thanks Mitchell,
    Monday, July 6, 2009 3:33 PM

  • Just noticed the shiny "MVP" tag.  Were you just awarded the MVP award as well?  If so, congrats!  Very well deserved, and in my opinion, way overdue. 
    Thanks David, I am glad we both got it, because you deserve congratulations for your work as well.

    In past years had always missed other MVP awards I was up for such as VSTO and WCF due to my primary work in the C# forums. So it was nice to get a C# MVP award.

    William Wegerson (www.OmegaCoder.Com)
    Monday, July 6, 2009 3:55 PM
  • Congrats to you both.  I could have sworn that David's was "hand written in" over these past weekend.  It was green over the weekend, and now it is black.  Now it looks more official.
    Mark the best replies as answers. "Fooling computers since 1971."
    • Proposed as answer by sabari prog Tuesday, January 25, 2011 11:39 AM
    Monday, July 6, 2009 4:03 PM
  • Congrats to you both.  I could have sworn that David's was "hand written in" over these past weekend.  It was green over the weekend, and now it is black.  Now it looks more official.
    Mark the best replies as answers. "Fooling computers since 1971."

    hehe.... It was handwritten in.  I couldn't wait.  :)  Thanks Rudy!
    David Morton - http://blog.davemorton.net/ - @davidmmorton - ForumsBrowser, a WPF MSDN Forums Client
    Monday, July 6, 2009 4:04 PM
  • I think I should win the MWP

    "Microsoft's Worst Percentage"

    :-)
    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Monday, July 6, 2009 4:07 PM