Jul 27 2009

Capability Classes & Queries

Category: C Plus Plus,C#,Philosophy,Software DevelopmentWil @ 7:41 pm

ostrich_headLast week, I had the honor and pleasure of teaching an Advanced C++ class at ExxonMobil in Houston, Texas. All of the students were brilliant and were employees in their Research division. I think I was the only one there without a PhD. In fact, several of them, had multiple doctorates or post-doctorates… which I didn’t even know existed.

But I digress. Since I hadn’t taught that class in about a decade and hadn’t used C++ professionally since circa 2003, my brain pushed a lot of my C++ knowledge out into its proverbial “garage” for later retrieval. After several days of submersion in the language and C++ labs, we finally got to some clever inheritance problems and polymorphism tricks. That brought back my long, lost memory of “Capability Classes and Capability Queries”.

While not exactly rocket science, Capability Queries can be of use in C# as well as C++. So here is what a capability class looks like… well, wait, let’s lay sound ground work first:

public class Animal { }
public class WarmBloodedAnimal : Animal { }

public class Human : WarmBloodedAnimal { }
public class Bird : WarmBloodedAnimal { }

Nothing really special there is there? Both birds and a humans are warm-blooded animals. So what?!

What if we had a collection of animals… say, just for arguments sake, a List collection. Now, you would like to only have a subset of that list… in which the resultant list is warm-blooded animals that have the ability of flight. Let’s ignore the fact that we have LINQ queries for now and just focus on the subject at hand. In some random method, we could do something like this:

public void SomeRandomMethod(IList<Animal> animals_)
{
   foreach (var animal in animals_)
      if (animal is Bird)
         (animal as Bird).Fly();
}

But, what about birds that can’t fly?! Penguins can’t fly but they’re excellent swimmers. Should we add an attribute to the Animal base class for “IsCapableOfFlight”? I think not. Why pollute the interface and thusly pollute every derived class with that attribute!?!

That brings us to Capability Classes (Interfaces in C#).

public interface CapableOfFlight
{
   public void Fly();
}
public class Eagle : Bird, CapableOfFlight { }
public class Parakeet : Bird, CapableOfFlight { }
public class Ostrich : Bird { }
public class Penguin : Bird { }

public void SomeRandomMethod(IList<Animal> animals_)
{
   foreach (var animal in animals_)
      if (animal is CapableOfFlight)
         (animal as CapableOfFlight).Fly();
}

Obviously, it would be awesome to use LINQ to do a query on that collection with a ‘where’ clause that used the “animal is CapableOfFlight” but just by itself… it’s quite nice.

Go green… don’t pollute your interfaces and keep your derived/implementer classes skinny!


Jul 11 2009

Comparing C++ and C# Virtual Invocations

Category: C Plus Plus,C#,Software DevelopmentWil @ 8:22 am

I ran across this post today when I was cruising around the awesomness that is the internet:
http://blogs.msdn.com/rakkimk/archive/2007/05/11/virtual-functions-explored-c-c-examples.aspx

While Rakki did an excellent job of explaining C++ virtual table construction and invocation, I believe C# developers would really like a little more “beef” on their side of the fence.  Therefore, I will do a little comparison between the two.  The differences are huge!

In C++, you cannot call a derived class virtual method from a base class constructor because the derived class virtual table hasn’t been created yet. In C#, you absolutely can. That is a major difference!

For example, take this code in C++:

class Base
{
   public:
   // All virtual method calls in constructors are static; not dynamic.
   Base ()  { Foo(); }
   virtual void Foo() { cout << "Base::Foo" << endl; }
};
class Derived : public Base
{
public:
   Derived () { Foo(); // Calls Derived::Foo }
   virtual void Foo() { cout << "Derived::Foo" << endl; }
};
int main ()
{
   Derived derived;
}

This displays:
Base::Foo
Derived::Foo

Now, take the same code in C#:

public class Base
{
   public Base () { Foo(); }
   public virtual void Foo() { Console.WriteLine("Base::Foo"); }
}
public class Derived : Base
{
   public Derived () { Foo(); }
   public override void Foo() { Console.WriteLine("Derived::Foo"); }
}
class Program
{
   static void Main() { new Derived(); }
}

This displays:
Derived::Foo
Derived::Foo

Why? Because in C#, the virtual table has already been setup. So when the base class constructors get called, the virtual method invocation inside the constructor is truly virtual and the actual derived class instance being created is invoked (dynamically). If this is not the behaviour you want, you need to use ‘new virtual’ on each derived class instead of ‘override’. If you do that, you will get the same behaviour as in C++.

Enjoy!

Tags:


Get Adobe Flash playerPlugin by wpburn.com wordpress themes