PC Review


Reply
Thread Tools Rate Thread

Dynamic bean instantiation (reflection???)

 
 
jerryau
Guest
Posts: n/a
 
      24th Apr 2007
Hi,

I am trying to dynamically create object instances based on a string
class name, and then I need to dynamically set values to these
objects, but I have no idea how to do this in C#. Here is the example
of what I need to do:

******Dog.cs******
namespace MySystem
{
public class Dog
{
private string name;

public string name
{
get { return name; }
set { name = value; }
}
}
}

******Cat.cs******
namespace MySystem
{
public class Cat
{
private string name;

public string name
{
get { return name; }
set { name = value; }
}
}
}

******SetAnimals.cs******
namespace MySystem
{
public class SetAnimals
{
string[,] animals = new string[,] {{"Dog","dogname1"},
{"Dog","dogname2"},{"Cat","catname1"}};

public IList setAnimals()
{
IList animalList = new ArrayList();

// Somehow dynamically create a new instance of an object and
add it to the animalList
// e.g. animals[0,0] is a Dog type, therefore dynamically
create a Dog class, and set the name
// for the just created Dog class taken from animals[0,1]
"dogname1"

return animalList;
}
}
}

Is what I'm trying to do possible in C#? Does anyone have any ideas
how this can be done?

Thanks,
Jerry

 
Reply With Quote
 
 
 
 
Niu Kun
Guest
Posts: n/a
 
      24th Apr 2007
I think the best solution for your problem can be found from the COM source.

Create a class which can spawn objects.
One method of the class take the type namestring for the class,
and inside the method contains an if-else-if-else... whick returns the
corresponding object.

Like this:

Class Spawn
{
public System.Object getInstance(string typeName)
{
if(typeName == "Dog")
return new Dog();
else if /* and so on */
}
}
jerryau wrote:
> Hi,
>
> I am trying to dynamically create object instances based on a string
> class name, and then I need to dynamically set values to these
> objects, but I have no idea how to do this in C#. Here is the example
> of what I need to do:
>
> ******Dog.cs******
> namespace MySystem
> {
> public class Dog
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
> }
>
> ******Cat.cs******
> namespace MySystem
> {
> public class Cat
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
> }
>
> ******SetAnimals.cs******
> namespace MySystem
> {
> public class SetAnimals
> {
> string[,] animals = new string[,] {{"Dog","dogname1"},
> {"Dog","dogname2"},{"Cat","catname1"}};
>
> public IList setAnimals()
> {
> IList animalList = new ArrayList();
>
> // Somehow dynamically create a new instance of an object and
> add it to the animalList
> // e.g. animals[0,0] is a Dog type, therefore dynamically
> create a Dog class, and set the name
> // for the just created Dog class taken from animals[0,1]
> "dogname1"
>
> return animalList;
> }
> }
> }
>
> Is what I'm trying to do possible in C#? Does anyone have any ideas
> how this can be done?
>
> Thanks,
> Jerry
>

 
Reply With Quote
 
Niu Kun
Guest
Posts: n/a
 
      24th Apr 2007
Or you can switch a class's HashCode.
That may be faster.

jerryau wrote:
> Hi,
>
> I am trying to dynamically create object instances based on a string
> class name, and then I need to dynamically set values to these
> objects, but I have no idea how to do this in C#. Here is the example
> of what I need to do:
>
> ******Dog.cs******
> namespace MySystem
> {
> public class Dog
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
> }
>
> ******Cat.cs******
> namespace MySystem
> {
> public class Cat
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
> }
>
> ******SetAnimals.cs******
> namespace MySystem
> {
> public class SetAnimals
> {
> string[,] animals = new string[,] {{"Dog","dogname1"},
> {"Dog","dogname2"},{"Cat","catname1"}};
>
> public IList setAnimals()
> {
> IList animalList = new ArrayList();
>
> // Somehow dynamically create a new instance of an object and
> add it to the animalList
> // e.g. animals[0,0] is a Dog type, therefore dynamically
> create a Dog class, and set the name
> // for the just created Dog class taken from animals[0,1]
> "dogname1"
>
> return animalList;
> }
> }
> }
>
> Is what I'm trying to do possible in C#? Does anyone have any ideas
> how this can be done?
>
> Thanks,
> Jerry
>

 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      24th Apr 2007
On Apr 24, 1:15 pm, jerryau <jerrya...@gmail.com> wrote:
> I am trying to dynamically create object instances based on a string
> class name, and then I need to dynamically set values to these
> objects, but I have no idea how to do this in C#. Here is the example
> of what I need to do:


<snip>

> Is what I'm trying to do possible in C#? Does anyone have any ideas
> how this can be done?


Sounds like you're after Spring.NET:
http://springframework.net

Jon

 
Reply With Quote
 
Stoitcho Goutsev \(100\)
Guest
Posts: n/a
 
      24th Apr 2007
Hi,

You need to use some form of reflection for this.
1. You can create a Type object for your class by calling Type.GetType and
providing the string name of the class.
2. You can use reflection to get to the constructor of the class and invoke
it or the easier way is to use Activator.CreateInstance method passing the
Type object as a parameter.


--
Stoitcho Goutsev (100)

"jerryau" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi,
>
> I am trying to dynamically create object instances based on a string
> class name, and then I need to dynamically set values to these
> objects, but I have no idea how to do this in C#. Here is the example
> of what I need to do:
>
> ******Dog.cs******
> namespace MySystem
> {
> public class Dog
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
> }
>
> ******Cat.cs******
> namespace MySystem
> {
> public class Cat
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
> }
>
> ******SetAnimals.cs******
> namespace MySystem
> {
> public class SetAnimals
> {
> string[,] animals = new string[,] {{"Dog","dogname1"},
> {"Dog","dogname2"},{"Cat","catname1"}};
>
> public IList setAnimals()
> {
> IList animalList = new ArrayList();
>
> // Somehow dynamically create a new instance of an object and
> add it to the animalList
> // e.g. animals[0,0] is a Dog type, therefore dynamically
> create a Dog class, and set the name
> // for the just created Dog class taken from animals[0,1]
> "dogname1"
>
> return animalList;
> }
> }
> }
>
> Is what I'm trying to do possible in C#? Does anyone have any ideas
> how this can be done?
>
> Thanks,
> Jerry
>



 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      24th Apr 2007
On Apr 24, 8:15 am, jerryau <jerrya...@gmail.com> wrote:
> Hi,
>
> I am trying to dynamically create object instances based on a string
> class name, and then I need to dynamically set values to these
> objects, but I have no idea how to do this in C#. Here is the example
> of what I need to do:
>
> ******Dog.cs******
> namespace MySystem
> {
> public class Dog
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
>
> }
>
> ******Cat.cs******
> namespace MySystem
> {
> public class Cat
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
>
> }
>
> ******SetAnimals.cs******
> namespace MySystem
> {
> public class SetAnimals
> {
> string[,] animals = new string[,] {{"Dog","dogname1"},
> {"Dog","dogname2"},{"Cat","catname1"}};
>
> public IList setAnimals()
> {
> IList animalList = new ArrayList();
>
> // Somehow dynamically create a new instance of an object and
> add it to the animalList
> // e.g. animals[0,0] is a Dog type, therefore dynamically
> create a Dog class, and set the name
> // for the just created Dog class taken from animals[0,1]
> "dogname1"
>
> return animalList;
> }
> }
>
> }
>
> Is what I'm trying to do possible in C#? Does anyone have any ideas
> how this can be done?
>
> Thanks,
> Jerry


To create the instance, I think you need
System.Activator.CreateInstance.
To set properties on the instance, you'll need to use GetType to get
the type, then get the PropertyInfo objects describing the
properties.. There's a method on PropertyInfo (SetValue, I think)
that will do what you need.

HTH
Andy

 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      24th Apr 2007
Niu Kun <(E-Mail Removed)> wrote:
> Or you can switch a class's HashCode.
> That may be faster.


Never assume that a hashcode will be unique - they're not guaranteed to
be unique.

However, your solution also assumes that all the required types are
known at compile-time. The benefit of reflection-based solutions is
that they're very neutral - you can load any type from any assembly
(within reason).

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
Tom Shelton
Guest
Posts: n/a
 
      24th Apr 2007
On Apr 24, 6:15 am, jerryau <jerrya...@gmail.com> wrote:
> Hi,
>
> I am trying to dynamically create object instances based on a string
> class name, and then I need to dynamically set values to these
> objects, but I have no idea how to do this in C#. Here is the example
> of what I need to do:
>
> ******Dog.cs******
> namespace MySystem
> {
> public class Dog
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
>
> }
>
> ******Cat.cs******
> namespace MySystem
> {
> public class Cat
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
>
> }
>
> ******SetAnimals.cs******
> namespace MySystem
> {
> public class SetAnimals
> {
> string[,] animals = new string[,] {{"Dog","dogname1"},
> {"Dog","dogname2"},{"Cat","catname1"}};
>
> public IList setAnimals()
> {
> IList animalList = new ArrayList();
>
> // Somehow dynamically create a new instance of an object and
> add it to the animalList
> // e.g. animals[0,0] is a Dog type, therefore dynamically
> create a Dog class, and set the name
> // for the just created Dog class taken from animals[0,1]
> "dogname1"
>
> return animalList;
> }
> }
>
> }
>
> Is what I'm trying to do possible in C#? Does anyone have any ideas
> how this can be done?
>
> Thanks,
> Jerry


Jerry,

It is indeed possible... Assuming that all the types exist in the
same assembly, and are therefore loaded (in other words, there are no
dynamic loading issues to consider) then you might implement it
something like this:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace ConsoleApplication8
{
class Program
{

static void Main ( string[] args )
{
foreach (Animal animal in GetAnimalList ( new string[][]
{ new string[] { "Dog", "Rover" }, new string[]{ "Dog", "Rex" }, new
string[]{ "Cat", "Erica" } } ))
{
animal.Vocalize ();
}
}

private static List<Animal> GetAnimalList ( string[][]
nameTypePairs )
{
List<Animal> animals = new List<Animal>();

foreach (string[] nameTypePair in nameTypePairs)
{
Animal animal = (Animal)Assembly.GetExecutingAssembly
().CreateInstance ( string.Format ( "ConsoleApplication8.{0}",
nameTypePair[0] ), false, BindingFlags.CreateInstance, null, new
object[] { nameTypePair[1] },
System.Threading.Thread.CurrentThread.CurrentCulture, null );
animals.Add ( animal );
}

return animals;
}
}

internal abstract class Animal
{
private string name;

protected Animal ( string name )
{
this.name = name;
}

public string Name
{
get { return name; }
}

public abstract void Vocalize ();
}

internal class Dog : Animal
{
public Dog ( string name ) : base ( name ) { }

public override void Vocalize ()
{
Console.WriteLine ( "{0} Says Bark!", this.Name);
}
}

internal class Cat : Animal
{
public Cat ( string name ) : base ( name ) { }

public override void Vocalize ()
{
Console.WriteLine ( "{0} Says Meow!", this.Name );
}
}
}

I hope this is enough to get you started...

--
Tom Shelton

 
Reply With Quote
 
Chris Dunaway
Guest
Posts: n/a
 
      25th Apr 2007
On Apr 24, 7:15 am, jerryau <jerrya...@gmail.com> wrote:
> Hi,
>
> I am trying to dynamically create object instances based on a string
> class name, and then I need to dynamically set values to these
> objects, but I have no idea how to do this in C#. Here is the example
> of what I need to do:
>
> ******Dog.cs******
> namespace MySystem
> {
> public class Dog
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
>
> }
>
> ******Cat.cs******
> namespace MySystem
> {
> public class Cat
> {
> private string name;
>
> public string name
> {
> get { return name; }
> set { name = value; }
> }
> }
>
> }
>
> ******SetAnimals.cs******
> namespace MySystem
> {
> public class SetAnimals
> {
> string[,] animals = new string[,] {{"Dog","dogname1"},
> {"Dog","dogname2"},{"Cat","catname1"}};
>
> public IList setAnimals()
> {
> IList animalList = new ArrayList();
>
> // Somehow dynamically create a new instance of an object and
> add it to the animalList
> // e.g. animals[0,0] is a Dog type, therefore dynamically
> create a Dog class, and set the name
> // for the just created Dog class taken from animals[0,1]
> "dogname1"
>
> return animalList;
> }
> }
>
> }
>
> Is what I'm trying to do possible in C#? Does anyone have any ideas
> how this can be done?
>
> Thanks,
> Jerry


If you store the type name in the array instead of just "Dog", then
you should be able to do it. You can get the type name with this:

System.Type t = typeof(Dog);
string typeName = t.Name;

Then, using the System.Reflection namespace, you can call

Activator.CreateInstance(typeName)

Look at the System.Reflection namespace for more information

Chris

 
Reply With Quote
 
Marc Gravell
Guest
Posts: n/a
 
      25th Apr 2007
> If you store the type name in the array instead of just "Dog", then
> you should be able to do it. You can get the type name with this:
>
> System.Type t = typeof(Dog);
> string typeName = t.Name;


but doesn't typeof(Dog).Name == "Dog" ???

Once you have created the object: for setting ad-hoc properties
without a common base / interface the preferred way is probably the
component model, i.e. to set the Name property:

object obj = Activator.CreateInstance(typeName);
TypeDescriptor.GetProperties(obj)["Name"].SetValue(obj, instanceName);

You can use reflection to talk to class properties, but the above is
more flexible in many ways - i.e. you can massage the available
properties at runtime (such as how datarow view works).

Marc


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic Instantiation =?Utf-8?B?RmFyaWJh?= Microsoft C# .NET 6 4th Jun 2006 07:05 AM
Dynamic Instantiation of Class =?Utf-8?B?a2lyYW4=?= Microsoft Dot NET Framework 1 3rd Aug 2005 12:20 PM
Object instantiation notification, AppDomain, Reflection =?Utf-8?B?RGF2ZSBM?= Microsoft Dot NET 7 15th Dec 2004 12:45 PM
Dynamic instantiation of a class Daniel Klein Microsoft VB .NET 3 26th Dec 2003 06:45 PM
Dynamic class instantiation Jim Witt Microsoft C# .NET 1 8th Nov 2003 12:36 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 05:13 PM.