Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Extending Polymorphism Backward in Class Hierarchy

0.00/5 (No votes)
19 Jun 2009 1  
This article explains how to apply polymorphic behavior back in the class hierarchy

Introduction

This article explains how to apply polymorphic behavior backward in the class hierarchy.

Using the Code

This article uses Visual Studio 2008.

The Problem

You may want to apply polymorphic behaviour to the classes of different levels of the inheritance hierarchy that do not have a common interface. For example, imagine that you have an array of objects of different types inherited from the same base class. You'd like to call a method for all the objects in the array, but the method only exists in one of the inherited classes.

The most reasonable thing would be to move the method up in the hierarchy (and make it virtual, if needed). However, it is not always in your hands - the base class can be in a third-party library, or inaccessible due to other reasons.

The Solution

Using an extension method will allow you to do the trick. Here is the example.

Create a base class called Animal. Assume it is the class that is out of your reach, and you cannot modify it.

public abstract class Animal
{
}

Create an inherited class DomesticAnimal that introduces the method Says(). This is the method you'd like to call across all the classes inherited from Animal.

public class DomesticAnimal : Animal
{
	public virtual string Says()
	{
		return null;
	}
}

Create classes Cat and Dog that inherit from DomesticAnimal and implement the method Says().

public class Cat : DomesticAnimal
{
	public override string Says()
	{
		return "Meow!";
	}
}

public class Dog : DomesticAnimal
{
	public override string Says()
	{
		return "Woof!";
	}
}

Create a class Wolf that inherits directly from Animal and thus does not have the Says() method.

public class Wolf: Animal
{
}

Now imagine a client code that creates an array of the above Animal objects and wants to call Says() method on each object in the array, including Wolf.

static void Main(string[] args)
{
	Animal[] animals = new Animal[3];
	animals[0] = new Cat();
	animals[1] = new Dog();
	animals[2] = new Wolf();

	foreach (Animal animal in animals)
	{
		Console.WriteLine("{0} says {1}", 
			animal.GetType().Name, animal.Says());
	}
}

Of course this code would not compile. The following error will show up, pointing to the Animal.Says() method:

'BackwardPolymorphism.Animal' does not contain a definition for 'Says' 
and no extension method 'Says' accepting a first argument of type 
'BackwardPolymorphism.Animal' could be found 
(are you missing a using directive or an assembly reference?)

Let's now add a new static class that will provide an extension method Says() for Animal class (note the same name of the extension and inherited methods). We have to check object type dynamically and cast the object in order to call the intrinsic Says() method of the inherited classes.

public static class AnimalExtension
{
	public static string Says(this Animal animal)
	{
		string says = "[Unknown]";

		if (animal is DomesticAnimal)
		{
			says = ((DomesticAnimal)animal).Says();
		}

		return says;
	}
}

Now the code will compile. When running, it produces the following output:

BackwardPolymorphism_src

History

  • 19th June, 2009: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here