Enumerating just derived classes

I have a base class and a derived class, which inherits from it.  These have a method that adds them to a Hashtable.  I am looping through the collection using a foreach, as such:

    foreach ( BaseClass bc in myHashtable )
    {
        bc.DoSomething();
    }

this will perform the DoSomething method for both the base and derived classes.  Is there an efficient way to extract just the derived classes or do I have to switch ( bc.GetType() )?  I have tried:

    foreach ( DerivedClass dc in myHashtable )
    {
        dc.DoSomething()
    }

but, if it hits a BaseClass object, I am told that it cannot cast from type BaseClass to DerivedClass.  

Is there a fast alternative?

J.
LVL 16
jimbobmcgeeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AlexFMCommented:
Such behaviour is one of main features of object-oriented programming. Derived class may be accessed by pointer to base class, virtual function is called according to current class type.
Make DoSomething virtual function which does nothing in the base class and does something you need in derived class. In this case code

    foreach ( BaseClass bc in myHashtable )
    {
        bc.DoSomething();
    }

will run exaclty as you need - DoSomething is called according to current class instance type.
Another way is to add new virtual function to base and derived classes, which calls DoSomething in derived class, and does nothing in base class. Call this function from foreach loop.
TheAvengerCommented:
I am not sure if your initial example is perfectly correct, because going over the Hashtable with foreach will actually return a DictionaryEntry object. Nevertheless, here is an example how to solve your question:

Hashtable myHashtable = new Hashtable();
myHashtable.Add (1, new BaseClass());
myHashtable.Add (2, new DerivedClass());

foreach (BaseClass bc in myHashtable.Values)
{
      if (bc.GetType() == typeof (BaseClass))
            continue;  // Skip objects that are of the base class

      MessageBox.Show (bc.ToString());
}
jimbobmcgeeAuthor Commented:
AlexFM;
>> add new virtual function to base and derived classes, which calls DoSomething in derived class
This is the way I am currently doing it.  


TheAvenger ;
>> going over the Hashtable with foreach will actually return a DictionaryEntry object
You're right -- I actually use foreach (BaseClass bc in myHashtable.Values)
>> if (bc.GetType() == typeof (BaseClass))


I agree that both methods work well enough, but I was wondering if there was a way to reduce the number of iterations -- both calling an empty virtual DoSomething and checking bc.GetType still require the making the call.

J.
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

TheAvengerCommented:
No, it is not possible to reduce the number of iterations. No matter what you write, the code will always need to get the object in order to check if it is of the type you request or not

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DivinityCommented:
Just a quick code saver. This code:

if (bc.GetType() == typeof (DerivedClass)) {
     bc.DoSomething();
}

can also be written as:

if (bc is DerivedClass) {
     bc.DoSomething();
}

Notice the "is" keyword, it replace the whole GetType() and typeof() thing.


TheAvengerCommented:
@Divinity: If you have more derived classes, this does not work
DivinityCommented:
How do you mean, more derived classes ? You can only derive from one class at a time. And I believe the "is" keyword also works for interfaces.
TheAvengerCommented:
You can have DerivedClass1, DerivedClass2, etc. all deriving from BaseClass. Then you need to do:

if (bc is DerivedClass1 || bc is DerivedClass2 || ....)

And if you add a new derived class, your code is no more correct
jimbobmcgeeAuthor Commented:
I guess I'm not going to be able to reduce the iterations.  Oh well, never mind.

Thanks to all.

J.
TheAvengerCommented:
You can be sure you can't reduce them. Even if you don't make them, .Net will make them.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.