Click here to Skip to main content
15,879,095 members
Articles / Programming Languages / C#

Extending Polymorphism Backward in Class Hierarchy

Rate me:
Please Sign up or sign in to vote.
3.00/5 (2 votes)
19 Jun 2009Public Domain2 min read 17.8K   8   2
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.

C#
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.

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

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

C#
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.

C#
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.

C#
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.

C#
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, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Question[My vote of 2] Extending Polymorphism Backward? Pin
Darchangel23-Jun-09 4:39
Darchangel23-Jun-09 4:39 
Your article is about a function that wraps a cast. I suppose you could have also just as easily wrapped an 'is'. Beyond showing that, I'm not sure I see the point. You haven't really altered polymorphism, you're just testing for a subclass. While this has merit, the title of your article suggests that you might be thinking of polymorphism the wrong way.
AnswerRe: [My vote of 2] Extending Polymorphism Backward? Pin
Stas Kashepava23-Jun-09 11:40
Stas Kashepava23-Jun-09 11:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.