473,565 Members | 2,770 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Dynamic cast possible?

Hi all,

I was wondering if anybody could enlighten me on the possibility of
dynamic casting. Or, well, whether or not I'm actually trying to do
this the right way.

What I have is a base class that several classes inherit from. From
time to time I need to add new inherited types so I want something that
is as versatile as possible, preferably not requiring naming all
subtypes in a switch statement.
What I want is to call a function (that every class that inherits from
the base type implents differently) but without knowing the specific
objects' types. I.e. I want to be able to (from a for loop) call this
function for every pet in a pet store without separating dogs from cats
in different arrays, but keeping them in an array of the base type.

A code snippet would look roughly as follows:
private string GetAnimalSound( string animal_name) { // This function is
in the program, not the base class or anything
BaseAnimal x = null;
switch(animal_n ame) {
case "dog": x = new Dog(); break;
case "cat": x = new Cat(); break;
}
x.AnimalType = "Pet"; // Set different properties that each type
implements
return x.ReturnSound() ; // defined as abstract in base class,
different implementation per inherited class
}

Now, adding support for new animals requires me to update the switch
statements for each function in the program, which I find sub-optimal.
Therefore I tried to cancel the switch out into something like:

x = (Type.GetType(a nimal_name))Act ivator.CreateIn stance(null,
animal_name).Un wrap();

which unfortunately does not work. Without the cast it will at least
compile, but I'm left with a System.Object instead of a MyNamespace.Dog
or Cat etc.
My hunch is that what I need is dynamic casting, but I could of course
be wrong. Who can help me out here and advise me on how to achieve this
goal?

Thanks in advance,

Chris

May 6 '06 #1
4 2193
> What I have is a base class that several classes inherit from. From
time to time I need to add new inherited types so I want something that
is as versatile as possible, preferably not requiring naming all
subtypes in a switch statement.
What I want is to call a function (that every class that inherits from
the base type implents differently) but without knowing the specific
objects' types. I.e. I want to be able to (from a for loop) call this
function for every pet in a pet store without separating dogs from cats
in different arrays, but keeping them in an array of the base type.
Based upon what you describe, polymorphism seems to do the job, it seems
your function should actually be in the object (which removes the switch by
replacing it with polymorphism) ...
Another pattern that is common is to use attributes on the types to allow
for string translations i.e.

[AnimalIdentifie r("Dog")] which can then be obtained through reflections to
avoid using a switch statement.

Cheers,

Greg Young
C# MVP

here's an example.

public abstract class Animal {
public abstract void Speak();
}

public class Dog : Animal {
public overrides void Speak() {
Console.WriteLi ne("Woof");
}
}

public class Cat : Animal {
public overrides void Speak() {
Console.WriteLi ne("Meow");
}
}

public class Cow : Animal {
public overrides void Speak() {
Console.WriteLi ne("Moo");
}
}

public Animal [] CreateAnimals() {
Animal [] ret = new Animal[3];
ret[0] = new Dog();
ret[1] = new Cat();
ret[2] = new Cow();
return ret;
}

Animal[] Animals = CreateAnimals() ;
foreach(Animal CurrentAnimal in Animals) {
CurrentAnimal.S peak();
}
"Zark3" <Za******@gmail .com> wrote in message
news:11******** **************@ e56g2000cwe.goo glegroups.com.. . Hi all,

I was wondering if anybody could enlighten me on the possibility of
dynamic casting. Or, well, whether or not I'm actually trying to do
this the right way.

What I have is a base class that several classes inherit from. From
time to time I need to add new inherited types so I want something that
is as versatile as possible, preferably not requiring naming all
subtypes in a switch statement.
What I want is to call a function (that every class that inherits from
the base type implents differently) but without knowing the specific
objects' types. I.e. I want to be able to (from a for loop) call this
function for every pet in a pet store without separating dogs from cats
in different arrays, but keeping them in an array of the base type.

A code snippet would look roughly as follows:
private string GetAnimalSound( string animal_name) { // This function is
in the program, not the base class or anything
BaseAnimal x = null;
switch(animal_n ame) {
case "dog": x = new Dog(); break;
case "cat": x = new Cat(); break;
}
x.AnimalType = "Pet"; // Set different properties that each type
implements
return x.ReturnSound() ; // defined as abstract in base class,
different implementation per inherited class
}

Now, adding support for new animals requires me to update the switch
statements for each function in the program, which I find sub-optimal.
Therefore I tried to cancel the switch out into something like:

x = (Type.GetType(a nimal_name))Act ivator.CreateIn stance(null,
animal_name).Un wrap();

which unfortunately does not work. Without the cast it will at least
compile, but I'm left with a System.Object instead of a MyNamespace.Dog
or Cat etc.
My hunch is that what I need is dynamic casting, but I could of course
be wrong. Who can help me out here and advise me on how to achieve this
goal?

Thanks in advance,

Chris

May 6 '06 #2


Zark3 wrote:
BaseAnimal x = null;
switch(animal_n ame) {
case "dog": x = new Dog(); break;
case "cat": x = new Cat(); break;
} Now, adding support for new animals requires me to update the switch
statements for each function in the program, which I find sub-optimal.


The "runtime-equivalent" of a switch is an IDictionary. You need to
dispatch from strings to "code that produces animal with that name":

public delegate Animal AnimalProducer( );
public class AnimalProducers ByString:
// implement yourself or by inheritance
IDicitionary<st ring,AnimalProd ucer>
{
public static AnimalFactoryBy StringGlobal =
new AnimalFactoryBy String(); // allow easy sharing
}

Now you can add animal-producers:

IDictionary<str ing,AnimalProdu cer> producers =
AnimalProducers ByString.Global ;
producers.Add(" dog", Dog.Make); // error if already reg'ed
producers["cat"] = Cat.Make; // replace if exists

and you can now dispatch:

BaseAnimal x = producers[animal_name]();

This is such a powerfull, efficient and easily usable technique for
runtime-dispatching, That it surprises that it's not promoted as a
pattern (that im aware of :)

BTW: I prefer it over the Visitor-pattern for dispatching virtually on
argument-type, you can use IDictionary<Typ e,...> and search the passed
type for an entry when caller invokes operator[Type].

--
Helge
May 6 '06 #3
Hi,
This looks like it will do exactly what I need!
I'd only like to ask you, you're using Animal, BaseAnimal and
AnimalProducer, AnimalFactory. Are these typo's or actually distinct
classes?
And as for "Dog.Make", is this a method that I should implement? Is
there a syntax to "just run the ctor"?
Even though I'm not completely understanding the code yet, I've got a
sneaking suspicion this is the way to go :)

Thanks!
Chris

May 6 '06 #4


Zark3 wrote:
Hi,
This looks like it will do exactly what I need!
Glad I understood your problem.
I'd only like to ask you, you're using Animal, BaseAnimal and
AnimalProducer, AnimalFactory. Are these typo's or actually distinct
classes?
The names are extrapolations from your example.

BTW: I'm assuming you don't *actually* have code that concerns animals
but that you are using the animals as an analogy.

<general naming rant>
I actually don't like "BaseAnimal ". I prefer just "Animal" for naming.

If you are defining behaviour, and not implementation, consider using an
interface, which you may decide to name IAnimal to fall inline with that
wierd hugarian-style-like naming convention.

If you have common structure (and possibly code) that most Animal
instances will like to share give it a name like
DefaultAnimalBe haviourProvider , or along those lines, making it's role
explicit in it's name.
</general naming rant>

Since C# doesn't have anonymous *declaration*, but only anonymous
*definition* of delegates, the delegate must have a name. The name
"AnimalProducer " is chosen to be descriptive of what an instance of the
delegate should do, which is produce a new animal.

The name AnimalFactory refers to the fact that the the responsibility
of (an instance of) this class is to create variations over the
"product" Animal. It also draws on the relation to the Factory pattern
in the GoF book (http://en.wikipedia.org/wiki/GoF).
And as for "Dog.Make", is this a method that I should implement? Is
there a syntax to "just run the ctor"?
You can think of Dog.Make as meta-syntax, it just means "anything that
makes a dog".

Incidentally, in C#-1, the simplest way to create a delegate for a
constructor is to declare a static method and have that call the
constructor and then delegate to that static method. So in C#-1 you
would probably actually implement public static Animal Make().

In C# 2 you could use anonymous delegates, like:

producers["dog"] = new delegate() { return new Dog(); }

Instead of making a static method.
Even though I'm not completely understanding the code yet, I've got a
sneaking suspicion this is the way to go :)


Hope you have a success with it.

--
Helge
May 7 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
8575
by: adrian | last post by:
hi all this is my first post to this group, so pls bear with me while i try to make some sense. i am trying to create a sproc which uses dynamic sql to target a particuar table eg. '.' and perform some actions. i am using @tableID as a passes parameter for the sproc.
4
8064
by: MD | last post by:
I am trying to create a dynamic SQL statement to create a view. I have a stored procedure, which based on the parameters passed calls different stored procedures. Each of this sub stored procedure creates a string of custom SQL statement and returns this string back to the main stored procedure. This SQL statements work fine on there own....
5
8004
by: Radde | last post by:
HI, Are ther any pitfalls for dynamic cast in type safe downcasting..
4
4946
by: Val | last post by:
Hi I am using a DynamicProxy (class that inherits from RealProxy). I don't know the type of my Transparant Proxy at compile time. Is there a possibility to have a dynamic casting object correctParams = new object for(int i... Type t = Type.GetType(tiB.GetTypeName()) DynamicProxy proxy = new DynamicProxy(t, orderedParams, tiA)...
6
6385
by: Philipp Schumann | last post by:
Hi, I have a need for "dynamic type casting": in other words, in a "MyConvert" method I get passed an Object "value" and a Type "type" and the method should attempt to convert value into type. Of course it first tries to obtain the appropriate TypeConverter. However, for some types there are no applicable type converters. Consider a...
8
4225
by: akolsen | last post by:
Hello there. This should be simple, but im having trouble anyway of getting it to work. I have a boxed object that i want to cast to its native type, but I would like to use reflection to do the typecasting. This is the regular way.
6
4084
by: DaTurk | last post by:
Hi, I have three interfaces lets call them parent, child-A, and child-B. I want to have one variable, that can be either child-A, or child-B at run time. I just can't seem to figure out how to do it. They both inherit from parent, and I tried holding a parent variable, and then casting it down to either of the children, but I can't see...
13
3026
by: DaTurk | last post by:
Hi, This is a question brought about by a solution I came up with to another question I had, which was "Dynamic object creation". So, I'm curious if you can dynamically cast an object. If you have two object which have a common base class, they can both be cast up to the base class, but if either of the child classes have unuque methods...
1
8422
by: Pacific Fox | last post by:
Hi all, I have a SQL statement that allows paging and dynamic sorting of the columns, but what I can't figure out without making the SQL a dynamic string and executing it, or duplicating the SQL statement between an IF and ELSE statement. Following is the SQL statement; set ANSI_NULLS ON
0
7666
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7888
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8108
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
7951
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
1
5484
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3643
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
2083
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1201
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
925
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.