Dynamic cast possible?

Z

Zark3

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_name) {
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(animal_name))Activator.CreateInstance(null,
animal_name).Unwrap();

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
 
G

Greg Young

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.

[AnimalIdentifier("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.WriteLine("Woof");
}
}

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

public class Cow : Animal {
public overrides void Speak() {
Console.WriteLine("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.Speak();
}
 
H

Helge Jensen

Zark3 said:
BaseAnimal x = null;
switch(animal_name) {
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 AnimalProducersByString:
// implement yourself or by inheritance
IDicitionary<string,AnimalProducer>
{
public static AnimalFactoryByStringGlobal =
new AnimalFactoryByString(); // allow easy sharing
}

Now you can add animal-producers:

IDictionary<string,AnimalProducer> producers =
AnimalProducersByString.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<Type,...> and search the passed
type for an entry when caller invokes operator[Type].
 
Z

Zark3

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
 
H

Helge Jensen

Zark3 said:
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
DefaultAnimalBehaviourProvider, 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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top