Search Unity

Instantiate a partic class from an array of a classes that inherit from an interface?

Discussion in 'Scripting' started by vreference, Nov 8, 2011.

  1. vreference

    vreference

    Joined:
    Mar 22, 2011
    Posts:
    154
    Hopefully this is an easy answer. I'm looking to create a new instance of a Mission class at runtime - I will have multiple mission classes so I want to select the right one and access it via an interface. So i'll be storing the reference to variable type iMission... the only trouble is I don't know how to store the array of classes. So I will have Mission_0, Mission_1, and mission_2 classes - all inherting from iMission and although I could easily do:
    iMission theMission = new Mission_1();

    I need to be able to select the proper class from an Array.
    How do I do assign the mission classes to an array of iMission(or whatever) without making new instances of them (as I need to construct them as required):
    iMission theMission = new missions[1]();
     
  2. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Use a generic collection.

    Code (csharp):
    1.  
    2. public interface iMission {
    3.  
    4. }
    5.  
    6. public class Mission : iMission {
    7.  
    8. }
    9.  
    10. public class MissionManager {
    11.  
    12.     List<iMission> missions;
    13.  
    14.     public void BuildMissionList()
    15.     {
    16.         missions = new List<iMission>();
    17.         missions.Add(new Mission());
    18.     }
    19. }
    20.  
     
  3. vreference

    vreference

    Joined:
    Mar 22, 2011
    Posts:
    154
    Seems like that would just be storing references to existing instances of a new class? I'd like to create the classes the same way I would with
    iMission theMission = new Mission_1();

    only as:

    iMission theMission = new x();

    or more specifically

    iMission theMission = new x[1]();
     
  4. willyfreddy

    willyfreddy

    Joined:
    Mar 28, 2011
    Posts:
    50
    Hi there,

    Assuming I understand what exactly it is that you're wanting, here is a simplistic example in C# of how to do it (using a base class instead of an interface - but the basic approach is the same).

    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections.Generic;
    4.  
    5. namespace ConsoleApplication1
    6. {
    7.     public abstract class classRoot
    8.     {
    9.     public delegate classRoot MyDelegate();
    10.     public static Dictionary<string, MyDelegate> classes = new Dictionary<string,MyDelegate>();
    11.         public static classRoot CreateAClass(string theName)
    12.         {
    13.             foreach (KeyValuePair<string, classRoot.MyDelegate> kvp in classes)
    14.             {
    15.                 if (kvp.Key == theName)
    16.                 {
    17.                     classRoot myClass = kvp.Value();
    18.                     return myClass;
    19.                 }
    20.             }
    21.            
    22.             return null;
    23.         }
    24.         public abstract void DoStuff();
    25.     }
    26.  
    27.     public class classA : classRoot {
    28.     public static classA CreateMe() { return new classA(); }
    29.         public static void Register() { classRoot.classes.Add("classA", CreateMe); }
    30.     public override void DoStuff() { Console.WriteLine("I got an A!"); }
    31.     }
    32.  
    33.     public class classB : classRoot {
    34.         public static classB CreateMe() { return new classB(); }
    35.         public static void Register() { classRoot.classes.Add("classB", CreateMe); }
    36.         public override void DoStuff() { Console.WriteLine("I only got a B :("); }
    37.     }
    38.  
    39.     class Program
    40.     {
    41.         static void Main(string[] args)
    42.         {
    43.             classA.Register();
    44.             classB.Register();
    45.  
    46.             classRoot myclass = classRoot.CreateAClass("classB");              
    47.         if ( myclass != null )
    48.             {
    49.                 myclass.DoStuff();
    50.             }
    51.     }
    52.     }
    53. }
    54.  
    There are probably better ways to do it (anyone else wan to chime in?), but this should allow you to do what you wanted.

    Hope that helps. Please let me know if any of it is unclear.

    Will
     
  5. willyfreddy

    willyfreddy

    Joined:
    Mar 28, 2011
    Posts:
    50
    For the sake of completeness, here's the same simplistic example but with an interface (as you wanted).

    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections.Generic;
    4.  
    5. namespace ConsoleApplication1
    6. {
    7.     public class classRoot
    8.     {
    9.     public delegate MyInterface MyDelegate();
    10.     public static Dictionary<string, MyDelegate> classes = new Dictionary<string,MyDelegate>();
    11.         public static MyInterface CreateAClass(string theName)
    12.         {
    13.             foreach (KeyValuePair<string, classRoot.MyDelegate> kvp in classes)
    14.             {
    15.                 if (kvp.Key == theName)
    16.                 {
    17.                     MyInterface myClass = kvp.Value();
    18.                     return myClass;
    19.                 }
    20.             }
    21.            
    22.             return null;
    23.         }
    24.     }
    25.  
    26.     public interface MyInterface
    27.     {
    28.         void DoStuff();
    29.     }
    30.  
    31.     public class classA : MyInterface {
    32.     public static classA CreateMe() { return new classA(); }
    33.         public static void Register() { classRoot.classes.Add("classA", CreateMe); }
    34.     public void DoStuff() { Console.WriteLine("I got an A!"); }
    35.     }
    36.  
    37.     public class classB : MyInterface {
    38.         public static classB CreateMe() { return new classB(); }
    39.         public static void Register() { classRoot.classes.Add("classB", CreateMe); }
    40.         public void DoStuff() { Console.WriteLine("I only got a B :("); }
    41.     }
    42.  
    43.     class Program
    44.     {
    45.         static void Main(string[] args)
    46.         {
    47.             classA.Register();
    48.             classB.Register();
    49.  
    50.             MyInterface myclass = classRoot.CreateAClass("classB");            
    51.         if ( myclass != null )
    52.             {
    53.                 myclass.DoStuff();
    54.             }
    55.     }
    56.     }
    57. }
    58.  
    It could still be a lot cleaner, but it'll get the job done. Again, let me know if anything is unclear.

    Will
     
    Last edited: Nov 17, 2011