IEnumerator & Dynamic (run-time) Casting.
Picture this scenario. You have two indexer classes that both implement IEnumerable. You know that the valid index range is in [0,1]. Due to the nature of the project, the two classes do not and will not have a base class. You then have two classes that build lists on these indexers, each of which extends a base class, which includes an abstract function to return an IEnumerable result.
class ClassA : IEnumerable
{
// n is valid in [0,1]
public this[int n] { get { ... } set { ... } }
}
class ClassB : IEnumerable
{
// n is valid in [0,1]
public this[int n] { get { ... } set { ... } }
}
abstract class ListBase
{
abstract IEnumerable GetList ();
}
class ListA : ListBase
{
override IEnumerable GetList { return list; }
}
class ListB : ListBase
{
override IEnumerable GetList { return list; }
}
Let's imagine that you wanted to build an HTML SELECT box on these lists. You might declare a variable of type ListA and a variable of type ListB, and process them. This is easy to do:
ListA A = new ListA();
ListB B = new ListB();
IEnumerable resultsA = A.GetList();
for (ListA rA in resultsA)
outHTML_A = "<option value='" + rA[0] + '">" + rA[1] + "</option>";
IEnumerable resultsB = B.GetList();
for (ListB rB in resultsB)
outHTML_B = "<option value='" + rB[0] + '">" + rB[1] + "</option>";
Now tweak the scenario a bit. You don't know at compile time which list will need to be turned into a SELECT box. You want to be able to declare a variable of type ListBase, and then at run-time call the GetList function and build your options list. The immediate problem is illustrated below (in the form of ????).
ListBase C;
// C has been set at run time to an instance of either ListA or ListB
IEnumerable resultsC = C.GetList();
for (???? rC in resultsC)
outHTML = "<option value='" + rC[0] + '">" + rC[1] + "</option>";
You don't know at run-time which indexer (ClassA or ClassB) is in the result set, but you need to know in order to both use the for (... in ...) iterator and access the indexers. You really would like to avoid writing a switch statement to determine which class it was, especially since you might add ClassC, ListC and ClassD, ListD, etc. in the future. Here-in lies a solid use for dynamic (run-time) casting. Can it be done, and how would you evaluate the type held inside the result set to know how to cast rC?
This is similar to what I'm actually doing using ASP.NET DataSets & TableAdapters. The key is that processing of the list happens in the base class, since it is the same regardless of which child class invoked the processing method.
Brandon
__________________
Brandon
|