You need to perform a particular action on a set of dissimilar objects contained within an array or collection, preferably without having to know each individual object’s type.
Use interfaces in a polymorphic
manner. The following interface contains a single method,
Sort
, which allows sorting to be performed on the
object that implements this interface:
public interface IMySort { void Sort( ); }
The next three classes implement the IMySort
interface. These classes all share the same Sort
method, but each class implements it in a different way:
public class CharContainer : IMySort { public void Sort( ) { // Do character type sorting here Console.WriteLine("Characters sorted"); } } public class NumberContainer : IMySort { public void Sort( ) { // Do numeric type sorting here Console.WriteLine("Numbers sorted"); } } public class ObjectContainer : IMySort { public void Sort( ) { // Do object type sorting here Console.WriteLine("Objects sorted"); } }
The SortAllObjects
method accepts an array of
objects :
public void SortAllObjects(IMySort[] sortableObjects) { foreach (IMySort m in sortableObjects) { m.Sort( ); } }
If this method is called as follows:
Obj.SortAllObjects(new IMySort[3] {new CharContainer( ), new NumberContainer( ), new ObjectContainer( )});
the following is displayed:
Characters sorted Numbers sorted Objects sorted
The foreach
loop is useful not only for iterating over individual elements in a
collection or an array, but also in iterating over a specific
interface implemented by each element in a collection or array. Using
this technique, interface members may be used in a similar manner on
each element, even if the elements are unrelated object types.
Consider the following array of objects:
Object[] objs = new Object[6] {new CharContainer( ), new NumberContainer( ), new CharContainer( ), new ObjectContainer( ), new NumberContainer( ), new ObjectContainer( )});
This array contains several objects of differing types. The one
thread of similarity that runs through each type is the
implementation of the IMySort
interface, defined
as follows:
public interface IMySort { void Sort( ); }
Passing the Objects
array in to the following
method allows each Sort
method to be called from
each object in the Objects
array:
public void SortAllObjects(object[] sortableObjects) { foreach (IMySort m in sortableObjects) { m.Sort( ); } }
The foreach
loop in this method is able to treat
each object in the sortableObjects
array in the
same way because each object in the
sortableObjects
array is cast to its
IMySort
interface and used as such.
If the foreach
loop encounters a
sortableObjects
array that contains one or more
objects that do not implement the IMySort
interface, an
InvalidCastException
will be thrown. To prevent an
exception from being thrown while at the same time allowing the
foreach
loop to iterate over all elements in the
sortableObjects
array, you can use the following
modified code:
public void SortAllObjects(object[] sortableObjects) { foreach (object o in sortableObjects) { IMySort sortObject = o as IMySort; if (sortObject!= null) { sortObject.Sort( ); } } }
This modified method will now test each element of the
sortableObjects
array to first determine whether
it can be cast to an IMySort
interface. If it can
be cast to this interface type, the variable
sortObject
will not be null
and
the if
statement will allow the
Sort
method on that object to be called.