Connecting Tech Pros Worldwide Forums | Help | Site Map

Dynamically selecting Class for use in program.

Member
 
Join Date: Sep 2009
Location: Usa, Michigan, Westland
Posts: 49
#1: 4 Weeks Ago
I have 10 Classes that just hold data. int and string data. Nothing fancy.

Yet. I have 10 possible selections from the user.
Based on the selection. I want to Instantiate a specific class.
Ver is the namespace the Data Classes are within.

I don't have an Interface for this, and am not sure if I should. All 10 classes will have the exact same name for the variables. Just different internal data.
I'll be running a huge loop (132 times) for this. So I would rather have this Dynamic method of declaring CurrentV so I don't have to do 10 repeats of the same code.

Expand|Select|Wrap|Line Numbers
  1. switch (ClassID) {
  2.  case 0: Ver.Data1 CurrentV = new Ver.Data1(); break;
  3.  case 1: Ver.Data2 CurrentV = new Ver.Data2(); break;
  4.  case 2: Ver.Data3 CurrentV = new Ver.Data3(); break;
  5.  }
This doesn't work... Any ideas?

tlhintoq's Avatar
Moderator
 
Join Date: Mar 2008
Location: Arizona, USA
Posts: 1,783
#2: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


So all of these 10 classes are derived from the same base class? That way they inherit all of these identical properties?
Familiar Sight
 
Join Date: Jul 2009
Location: Calgary, Alberta, Canada
Posts: 233
#3: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


In addition to what tlhintoq said (you will need to use a base class) the reason your code doesn't work is because you're defining CurrentV in the switch block. When you exit, you go out of scope and lose your data :)

This is why you need the base type, so you can assign your generic data to it in your switch statement. Additionally, you can still tell what type it is...

example:
Expand|Select|Wrap|Line Numbers
  1. MyBaseType data = null;
  2. switch (ClassID)
  3. {
  4.   case 0: data = new Data0(); break;
  5.   case 1: data = new Data1(); break;
  6.   ...
  7.   case n: data = new DataN(); break;
  8. }
  9.  
  10. ...
  11. // We can tell what data is with the "is" statement
  12. if (data != null)
  13. {
  14.   if (data is Type0) Console.WriteLine("We have something of Type0!");
  15.  
  16.   // or more specifically...
  17.   Console.WriteLine(data.GetType().ToString());
  18. }
Here's the MSDN on inheritance. There's plenty more to be found via Google if this doesn't explain it well enough for you.

http://msdn.microsoft.com/en-us/library/ms173149.aspx

Good luck!
Member
 
Join Date: Sep 2009
Location: Usa, Michigan, Westland
Posts: 49
#4: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


I never really did get the Inheritance concepts really.
Also I don't have any methods within these classes. Its all just data variables.

Ugh. Im lost. =\
Member
 
Join Date: Sep 2009
Location: Usa, Michigan, Westland
Posts: 49
#5: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


Unfortunally. Regardless of inheritance, Istill have different data sets, different class calls. Inheritance is only going to give me a generalized data set standard... It does nothing for me.
Familiar Sight
 
Join Date: Jul 2009
Location: Calgary, Alberta, Canada
Posts: 233
#6: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


Yes but you're using a common type to hold the specific types so you can only deal with one variable.

Here's a quick and dirty example, I'm going to use public members to cut down on typing, you probably shouldn't code like this ;)

Declare some types...
Expand|Select|Wrap|Line Numbers
  1. class BaseType
  2. {
  3. }
  4.  
  5. class DataType1 : BaseType
  6. {
  7.   public int Age;
  8. }
  9.  
  10. class DataType2 : BaseType
  11. {
  12.   public string Name;
  13. }
Now decide what's kind of data we're going to set up.
Expand|Select|Wrap|Line Numbers
  1. BaseType myItem = null;
  2. int flag = 0; // or whatever you want
  3. switch (flag)
  4. {
  5.   case 0:
  6.   {
  7.     DataType1 newItem = new DataType1();
  8.     newItem.Age = 27;
  9.     myItem = newItem;
  10.     break;
  11.   }
  12.   case 1:
  13.   {
  14.     DataType2 newItem = new DataType2();
  15.     newItem.Name = "GaryTexmo";
  16.     myItem = newItem;
  17.     break;
  18.   }
  19. }
myItem is going to contain the data you want, but it won't be accessible because myItem is of type BaseType, which has absolutely nothing in it. If I want to access the data, I can do the following...

Expand|Select|Wrap|Line Numbers
  1.             if (myItem != null)
  2.             {
  3.                 if (myItem is DataType1)
  4.                 {
  5.                     Console.WriteLine("Item is DataType1...");
  6.                     Console.WriteLine("  Age is " + ((DataType1)myItem).Age);
  7.                 }
  8.                 else if (myItem is DataType2)
  9.                 {
  10.                     Console.WriteLine("Item is DataType2...");
  11.                     Console.WriteLine("  Name is " + ((DataType2)myItem).Name);
  12.                 }
  13.                 else
  14.                 {
  15.                     Console.WriteLine("Unrecognized type...");
  16.                 }
  17.             }
So while inheritance gives you the generalized type to pass around your program, you can always get back to the more specific type. This is what you said you wanted to do in your first post.

Your alternative would be to create a whole bunch of member variables for each type and assign them to null, only ever accessing the one for the type you want. This will work, but it's a lot of overhead and wasted code.

Does that help any?
Member
 
Join Date: Sep 2009
Location: Usa, Michigan, Westland
Posts: 49
#7: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


So basicly what your trying to hint at is this...

Declare a class with all the properties setup, then toss the data into those properties at run time when user makes selection...

This is the fundamental reason why I'm tryin to figure this out in the first place...
Data store and retrieval. If I really can't use a predefined class with data in it... Now what? *sigh*
Familiar Sight
 
Join Date: Jul 2009
Location: Calgary, Alberta, Canada
Posts: 233
#8: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


No, that's what I'm saying you should NOT do :) I'm saying you should use a base type to store whatever you need instead of instantiating an object for each specific type. Hence the code I posted.

I keep going over what you wrote in your original post and it sounds like this is pretty much what you need. Am I understanding you incorrectly? Perhaps you can further define what you're trying to do.

I apologize if I'm misunderstanding you.
Newbie
 
Join Date: Oct 2009
Posts: 2
#9: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


You can use Reflection to instantiate the class if you can have the full path with namespace as a string.

string Namespace = "ABC.MyCode";
string fullPath = NameSpace + "." + "Data" + ClassID ;

Assembly ass = Assembly.GetExecutingAssembly();
object o = ass.CreateInstance(fullPath);

To get a property you can use reflection again.

NOTE: Reflection is not very efficient but its good sometimes.
Member
 
Join Date: Sep 2009
Location: Usa, Michigan, Westland
Posts: 49
#10: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


Gary, This is basically what I have on my program right now.
Expand|Select|Wrap|Line Numbers
  1. public class TClass1 {
  2.   int[] TPoints1;
  3.   int[] TPoints2;
  4.   int[] TPoints3;
  5.  
  6.   string[] TTitles1;
  7.   string[] TTitles2;
  8.   string[] TTitles3;
  9.  
  10.   string[] TIconImg1;
  11.   string[] TIconImg2;
  12.   string[] TIconImg3;
  13.  
  14.   string[][] TDiscription1;
  15.   string[][] TDiscription2;
  16.   string[][] TDiscription3;
  17.   }
That is the exact setup. Lacking the actual data.
And mind you I have only the first 2 classes 100% finished and filled with data, and the file is over 100k in text. So forgive me if I don't post it. =P

Besides Gary, I'm the one misunderstanding. Lol. I don't get the above posted code... Sorry!

>>PMohanta
Neat piece of code! That reminds me of PHP so much. lol. I resume my coding in the morning. I'll see what that thing does. =D
Familiar Sight
 
Join Date: Jul 2009
Location: Calgary, Alberta, Canada
Posts: 233
#11: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


What are you looking to do with that code, though? I thought I understood your fundamental question from your top post, but now I'm not so sure.

Quote:

Originally Posted by Samishii23 View Post

Besides Gary, I'm the one misunderstanding. Lol. I don't get the above posted code... Sorry!

If that's the case then play around with it. You should be able to put that code into your compiler and test it. This is no different than how every class in C# inherits from object. So you can assign an integer to an object, or a string to an object... as such:

Expand|Select|Wrap|Line Numbers
  1. object myObj = 5;
  2. object myObj2 = "this is a test";
Try reading through a few google articles on inheritance... even if it turns out to not be what you're looking for, it will certainly come in handy at some point :)
Member
 
Join Date: Sep 2009
Location: Usa, Michigan, Westland
Posts: 49
#12: 4 Weeks Ago

re: Dynamically selecting Class for use in program.


This is the do something function when the user makes the selection.
This is the very first version of it, so it'll be messy. Its the first step, and not the last. I have much much more to add to it still. Not even joking. lol.

Expand|Select|Wrap|Line Numbers
  1. List<Image> IconCache = new List<Image>();
  2. List<Image> IconCacheGrey = new List<Image>();
  3. List<Image> TalentBGCache = new List<Image>();
  4. List<Image> ClassIcon = new List<Image>();
  5.  
  6. public void BringUpClass(int ClassID) {
  7.  string TC = "v322";
  8.  switch (ClassID) {
  9.   case 0: TC = TC + ".DeathKnight"; break;
  10.   case 1: TC = TC + ".Druid"; break;
  11.   }
  12.  
  13.  // Haven't implement this yet. But going to later.
  14.  Assembly ass = Assembly.GetExecutingAssembly();
  15.  object o = ass.CreateInstance(TC);
  16.  
  17.  v322.DeathKnight CurrentV = new v322.DeathKnight();
  18.  
  19.  // Cache Class BG Images
  20.  foreach( string fe in CurrentV.TBGImage ) {
  21.   Bitmap TempBGBitmap = new Bitmap(GData.DirOther + fe);
  22.   Image TempCopy = Image.FromHbitmap(TempBGBitmap.GetHbitmap());
  23.   TalentBGCache.Add(TempCopy);
  24.   }
  25.  
  26.  // Cache Talent Icons
  27.  // -- Tree 1 Icons
  28.  foreach (string fe2 in CurrentV.TIconImg1) {
  29.   if (fe2 != null) {
  30.    Bitmap TempBitmap2 = new Bitmap(GData.DirIcon + fe2);
  31.    Image TempCopy = Image.FromHbitmap(TempBitmap2.GetHbitmap());
  32.    IconCache.Add(TempCopy);
  33.    Image TempCopy2 = Image.FromHbitmap(GrayImg(TempBitmap2).GetHbitmap());
  34.    IconCacheGrey.Add(TempCopy2);
  35.    }
  36.   }
  37.  
  38.  // -- Tree 2 Icons
  39.  foreach (string fe2 in CurrentV.TIconImg2) {
  40.   if (fe2 != null) {
  41.    Bitmap TempBitmap3 = new Bitmap(GData.DirIcon + fe2);
  42.    }
  43.   }
  44.  
  45.  // Cache Background Images
  46.  foreach (string fe3 in CurrentV.TBGImage) {
  47.   Bitmap TempBitmap3 = new Bitmap(GData.DirOther + fe3);
  48.   Image TempCopy = Image.FromHbitmap(TempBitmap3.GetHbitmap());
  49.   TalentBGCache.Add(TempCopy);
  50.   }
  51.  
  52.  // Build the Talent Backgrounds
  53.  PictureBox[] TBGImg = new PictureBox[3];
  54.  int i_bg = 0;
  55.  foreach (int fe4 in GData.DTreeX) {
  56.   TBGImg[i_bg] = new PictureBox();
  57.   TBGImg[i_bg].Location = new Point(fe4, GData.DTreeY);
  58.   TBGImg[i_bg].Size = new Size(GData.DTreeBGW, GData.DTreeBGH);
  59.   TBGImg[i_bg].Image = TalentBGCache[i_bg];
  60.   TBGImg[i_bg].Visible = true;
  61.   this.Controls.Add(TBGImg[i_bg]);
  62.   i_bg++;
  63.   }
  64.  
  65.  // Build Tree 1
  66.  PictureBox[] TTree1 = new PictureBox[44];
  67.  int i_t1 = 0;
  68.  int i_ico = 0;
  69.  foreach (int fe5y in GData.DTIconY)
  70.  foreach (int fe5x in GData.DTIcon1X) {
  71.   if (CurrentV.TPoints1[i_t1] != 0) {
  72.    TTree1[i_t1] = new PictureBox();
  73.    TTree1[i_t1].Location = new Point(fe5x, fe5y);
  74.    TTree1[i_t1].SizeMode = PictureBoxSizeMode.StretchImage;
  75.    TTree1[i_t1].Size = new Size(GData.DIcoW, GData.DIcoH);
  76.    TTree1[i_t1].Image = IconCache[i_ico];
  77.    TTree1[i_t1].Visible = true;
  78.    this.Controls.Add(TTree1[i_t1]);
  79.    TTree1[i_t1].BringToFront();
  80.    i_ico++;
  81.    }
  82.   i_t1++;
  83.   }
  84.  
  85.  // Build Tree 2
  86.  PictureBox[] TTree2 = new PictureBox[44];
  87.  int i_t2 = 0;
  88.  int i_ico = 0;
  89.  foreach(int fe6y in GData.DTIconY)
  90.  foreach (int fe6x in GData.DTIcon2X) {
  91.   if (CurrentV.TPoints2[i_t2] != 0) {
  92.    TTree2[i_t2] = new PictureBox();
  93.    TTree2[i_t2].Location = new Point(fe6x, fe6y);
  94.    TTree2[i_t2].SizeMode = PictureBoxSizeMode.StretchImage;
  95.    TTree2[i_t2].Size = new Size(GData.DIcoW, GData.DIcoH);
  96.    TTree2[i_t2].Image = 
  97.    /////////
  98.    ///////// This is where I left off on coding. Will ne finished at another time
  99.    }
  100.   }
  101.  }
Remember is the very first version of all the practice projects in the past in one method. Its sloppy, and in-efficient. But I hope to learn from it and maybe find a better way of doing it.
Reply

Tags
c sharp, classes, loop


Similar C# / C Sharp bytes