Collections in C# – The Queue

Most .Net developers are familiar with the ArrayList collection. The ArrayList has become a stable in most .Net applications, replacing in most cases the array. But did you know there are other types of collections?

This will begin a series discussing some of the other types of collections available in C#, and how to use them. Most are pretty straight forward, it’s just a matter of getting to know them. We’ll start things off with the queue.

A queue is a type of first in – first out, or FIFO collection. Unlike an array list, you must read things in order. Queues are very structured, you can’t go sifting or randomly plucking data out of the middle of the collection. OK, I can see you out there, scratching your head and asking “well why would I want to use a queue if it’s not as flexible as an arraylist?”

In a way you’ve answered your own question. Because queues are very structured, you can ensure that your application (or consumers of your application) can’t violate your intent.

Queue’s are simple, they have a grand total of three methods and one property. The property, Count, is almost self explanatory. It tells you how many items are in the Queue.

To get data into the queue, use the Enqueue method. Using the Dequeue method will return the next item, removing it from the collection. What if you want to see what the next item is, but don’t want to remove it? You can use the final method, Peek. Let’s take a look at a sample, done as a Console application.  

      Queue myQueue = new Queue();

      myQueue.Enqueue(“1. Carl Franklin”);

      myQueue.Enqueue(“2. Richard Campbell”);

      myQueue.Enqueue(“3. Mark Miller”);

      myQueue.Enqueue(“4. Kimberly Tripp”);

      myQueue.Enqueue(“5. Billy Hollis”);

 

      Console.WriteLine(“Count = “ + myQueue.Count.ToString());

      while (myQueue.Count > 0)

      {

        Console.WriteLine(myQueue.Dequeue());

      }

      Console.WriteLine(“Count = “ + myQueue.Count.ToString());

 

      Console.ReadLine();

 

This routine prints the following output to the command window:

[Pic of Queue Output Example 1]

 

As you can see, the Dequeue method returned the items in the same order they were loaded in. There’s really not much to explain, you load objects into the queue using Enqueue (in this case strings), and remove objects using Dequeue.

I also mentioned a Peek method. This allows you to look at the next item without removing it. Here I’ve modified the while loop to first show the next item on the queue using peek, then actually remove it.

 

      while (myQueue.Count > 0)

      {

        Console.WriteLine(“The next DNR person is:” + myQueue.Peek());

        Console.WriteLine(“Dequeuing them……..:” + myQueue.Dequeue());

      }

 

[Pic of Queue Output Example 2]

 

There are several instances where you may want to use a queue over an array list. Perhaps you are processing messages, or are reading through a list where it’s important you read them in order, say a list of transactions from a database. Data that needs to be processed chronologically could be placed on a queue.

Any time you have data that must be processed in the order in which it was loaded, use a queue. The rigidity of the queue will add an extra layer of safety to your application, ensuring data is read in the order in which you intended.

Arcane Thoughts: Designing for Use

Last week I traveled on business, and the hotel I stayed in had some interesting features that got me to pondering the dilemma of design versus usability. In the bathroom the sink looked like a piece of furniture. Four wooden legs held up a black marble table, atop of which was a large white bowl which was in fact the sink.

Visually, this was quite pleasing, the colors worked well, the contours were pleasing to my eye. The issue came when I tried to actually use the area. There was virtually no counter top area to work with. I had a very tiny space to put my contact lens stuff and my shaving kit. Further, there was no place to sit the hand towel while I was scraping my whiskers or putting my eyeballs in. This was a classic case where the builder went with a design that was visually pleasing over one that was usable.

Another conflict I found was the frosted glass that divided the bathroom from the bedroom. Where the frosted glass pane was located, if someone got up during the night to, well you know, and turned on the light, the light would hit right in the face of the person remaining in the bed. (Since I was alone it was a non issue, but if I’d been with my wife it could have been a problem.) In this case it was something with a design that looked good having negative side effects when put into use.

Lest you think I’m all whiny, there were some good points to the place, such as the closet. When I opened the closet door, the light came on. Didn’t have to think about it, didn’t have to fumble for a switch, it just worked. Simple yet very effective and pleasing.

My point on this post is not to complain about hotel rooms but to get you to think about design versus usability when it comes to your applications. How many websites have you been to that were confusing or hard to use, but visually stunning.

A good example of a bad example is Brown University. (http://www.brown.edu/). If you try to put your mouse over a menu item in an area that is collapsed, that area pops up to show a pretty picture. You then have to slide your mouse up to be able to click on the item you were just hovering on a second ago, before the page helpfully slid the menu up to show you a pretty picture you probably don’t care about. Visually, the effect is cool and the page looks nice, but if you are trying to actually click on a menu option it sucks.

On the other hand, let me mention my favorite site, Google (http://www.google.com). Yes, I said Google. It’s simple, not too much being thrown at you, and it’s obvious what I’m supposed to do (type something in and click Search). Like the light in my hotel room’s closet, it just works.

Windows Presentation Foundation (WPF) included in the new .Net 3.0 Framework gives us some powerful new tools for designing beautiful applications. Like all new technologies, this can be a double edged sword. I hope this post gets you to spend some time thinking about the user experience. Be sure the pretty pictures and cool effects don’t actually get in the way of getting the job done. Spend some time actually using your app. Key in data, do searches, etc. In short, be sure your program isn’t so pretty it’s ugly.

Installing openSUSE 10.2 on Virtual PC Step by Step

My “Installing Ubuntu on VirtualPC Step by Step” post (https://arcanecode.wordpress.com/2006/12/19/installing-ubuntu-on-virtualpc-step-by-step/) continues to be one of the top read posts on my blog each day. I thought it was about time to look at another Linux distribution, openSUSE.

In November 2006 Microsoft and Novell announced a new initiative, stating they were collaborating on Linux / Windows interoperability. Read the full press release at http://www.microsoft.com/presspass/press/2006/nov06/11-02MSNovellPR.mspx or http://shrinkster.com/lwl.

In the spirit of collaboration, many of you may wish to explore openSUSE but may not have a spare machine to use it on. VirtualPC is the answer to your problem.

Before we begin, you’ll need to download a few components. First, you need Microsoft VirtualPC itself. http://www.microsoft.com/windows/virtualpc/default.mspx or http://shrinkster.com/lwm. I’m using the 2007 Beta RC1, but this should work with 2004 as well. Previously I’ve installed openSUSE 10.1 on VirtualPC 2004 with no problems.

Next you will need the openSUSE.distribution, http://en.opensuse.org/Welcome_to_openSUSE.org or http://shrinkster.com/lwn is the place to grab it.

Be warned OpenSUSE ISO image is quite large, you’ll be a while downloading it. You will probably want to burn it to a DVD. If you don’t have a DVD burner handy, you can also use the Microsoft Virtual CD tool (which will work for DVDs too). I blogged about it at https://arcanecode.wordpress.com/2006/09/13/.

A quick note, there are, as of this writing some issues with openSUSE 10.2 not recognizing the sound drivers with Virtual PC 2007 RC1. If sound is important to you, consider staying with Virtual PC 2004, or use openSUSE 10.1. As sound wasn’t that big of a deal, I used 10.2 and VPC 2007, but I’ve also installed 10.1 under VPC 2004 and my experience was almost identical to what I write about here.

Finally before you get started, spend a few minutes getting familiar with VirtualPC if you have not already done so. You can find my step by step instructions for VirtualPC at https://arcanecode.wordpress.com/2006/09/20/virtual-pc-step-by-step/. Keep it handy, at various points I will be referring to it.

Like now. In Step 1 of my VirtualPC Step by Step you are instructed to create a new machine, please do so. I’ve named mine “openSUSE”. In step 2, you are prompted for your OS. You will need to pick Other. In step 3, you are asked about Ram. openSUSE will run OK under 256 megs, however if you have the available space I’d highly suggest upping it to 512, especially if you intend to get into doing some graphics or mono coding.

In step 4 you will want to create a new hard disk, and in step 5 confirm what you’ve selected. OK, now you are up to step 6, installing the OS, which is where this tutorial picks up.

The first thing you will see is the boot screen. Here it asks if you want to boot from the hard drive (you can’t as nothing’s installed yet on your virtual hard disk) or install in a variety of methods. Hit the down arrow so “Install” is highlighted and hit the Enter key.

[openSUSE 01]


The screen will turn blue, churn for a bit, then black with a little clock. Be patient, it’s working. Finally, you get to see a screen to begin your installation journey. On the first one, you get to select which language you want. Select your language of choice, and click next.

[openSUSE 02]


Next you are shown the license agreement. If you are hyped up on Jolt Cola and Double Espressos and need some sleep go ahead and read through it. Otherwise, click the “Yes I agree”, then click next.

[openSUSE 03]


Now you are asked what mode you are doing the install in. Since this is a fresh machine the only valid option is New Installation. If there had been an older version of openSUSE on the machine you would also have the upgrade option. For now, take the default of New Installation and click Next.

[openSUSE 04]


The openSUSE installer will now do some System Analysis. It will read over your system and produce you a list of what it’s going to install. It’ll take a minute or two, so be patient.

On the next screen you are asked about the Time Zone. Pick the time zone you live in and press next.

[openSUSE 05]


Now comes your first difficult decision. openSUSE wants you to pick a default desktop. Unlike Windows, Linux will let you pick from a variety of desktop shells. The desktop defines the look and feel of what you see as you interact with the computer.

If you are a Windows user, you might be more comfortable with the KDE desktop. It has a start bar and “K” menu across the bottom. On the other hand Gnome has something more akin to a look and feel from the Mac line. There are others out there, but these are the top two.

There’s one other item to take into consideration. If you intend to do any coding using Mono, you will need to use the Gnome desktop. The last time I checked, the majority of the Mono development tools were designed for the Gnome desktop. (I don’t claim to be a Mono expert, so if this is incorrect please feel free to leave an enlightening comment.) Mono, by the way, is the open source implementation of the Microsoft .Net Framework. Using Mono you can write C# code for a Linux environment.

Don’t stress over this too much. The nice thing about Linux is you can change your mind later, or you can try out a new desktop just to see what it’s like without making a permanent change to your default desktop.

Since one day I hope to dabble in Mono, I will pick the Gnome desktop and click Next.

[openSUSE 06]


OK, getting close. Now openSUSE will show you an installation summary, with everything it’s going to do and install. Give it a glance, and if you are happy with your options click Next.

[openSUSE 07]


This is where the folks at Novell like to play an April Fool joke, in that you only thought you were done with license agreements. In the 10.2 version I downloaded, I’m additionally asked to confirm the licenses for some Adobe product and the Flash player. I clicked OK on both.

[openSUSE 08]

[openSUSE 09]


OK, openSUSE asks you one last time if you are sure. We are (well at least I am) so click Install to begin the install.

[openSUSE 10]


Now sit back and wait. And wait. And wait some more. This thing takes a long time to install, for me the counter started at over 2 hours, although in the end it didn’t take that long.

First you’ll see some screens that talk about preparing your hard disk. Don’t worry, it’s the virtual disk it’s formatting, you’re safe. Finally you’ll see this screen as it begins the process.

[openSUSE 11]


Over to the right you’ll see the count down timer, and the center part will change during the install, giving you nice little tidbits and tricks. This would be a good time to refill your coffee, put some Jolt Cola on ice and order that pizza. You’ll be sitting here a while. (While you’re waiting might be a good time to explore some of my other posts, LOL.)

One real important thing: if your VirtualPC screen goes blank during the install, don’t freak out! Believe it or not, the screen saver is actually active during the install. All you have to do is click inside the VirtualPC window. The screen will then update to show you where it’s at in the install process.

After it’s finally done, it will tell you it’s going to reboot. Go ahead and let it, obviously. If you do nothing, the machine will reboot itself.

After the reboot you’ll see the same screen you saw when you first started, assuming you didn’t eject the openSUSE dvd. Pick the “Boot from Hard Disk” option, or if you do nothing it will take it as the default.

[openSUSE 12]


The next screen asks if you want the default of openSUSE 10.2, to boot off of Floppy, or the Failsafe mode for 10.2. Failsafe is kind of like Safe Mode under XP. Normally you’ll pick the openSUSE 10.2 option, which is what we will do now. (Doing nothing by the way will automatically select this.)

[openSUSE 13]


After the system finally gets done rebooting, there are some final installation steps that need to take place. First, you are taken to a screen and asked what you want the root user password to be. This is the master password for the system, you need this to install software or do any serious maintenance. Enter something secure, but easy to remember. Most of all don’t forget it, or your lovely Linux install will become severely handicapped. Enter your chosen password now, then click next.

[openSUSE 14]


Next you are prompted for a host name and domain name. Take the defaults and click Next.

[openSUSE 15]


In the next window you are asked about the network configuration. Be patient while openSUSE examines your virtual system. When done, just click Next to take the defaults it finds.

[openSUSE 16]


At the end of the network configuration, openSUSE wants to test your connection. Assuming you are connected to the web, leave Yes selected and click next to perform the test. Now, when I tried to do the test, it kept failing on me. I puzzled, fumed, changed things, but could find nothing wrong.

Finally, out of desperation, I clicked the Back button to return to the screen below, then told it to skip the test, and go on. By golly, it actually worked just fine! I guess the problem is on the Novell end, as openSUSE happily proceeded to download all sorts of online updates with no problems. Your experience may vary a little, but if you try the test and it fails, try using the Back button, tell it No, skip the test, and go on from there. I’m betting it’ll work OK for you too.

[openSUSE 17]


The online update is next, here openSUSE will try to download the latest patches and what-not for your system. You have the option to skip by picking No, but I would suggest you let it run so you can have all the latest security updates and bug fixes. (Note if you are not hooked to the internet, or were unable to get the networking to work, you will want to skip this step.)

As the first step in the updates, you are asked about additional installation sources. For now, take the defaults as shown and tell it Yes, to register the checked sources.

[openSUSE 18]


You will now see a series of update screens flash by as your system is updated from the internet. The screen will look something like this:

[openSUSE 19]

Just let it go, it will take a bit (especially if you have a slow connection). When it’s done openSUSE will automatically take you to the next area.


In this next area you are prompted for users. First, you are asked about the method for authenticating users. There are some nice options here, including the ability to check against a windows domain. For our purposes though, the default of Local (/etc/passwd) will do just fine, so click Next.

[openSUSE 20]


Next you are prompted for user info. Enter your name, what user name you’d like to have, and a password for that user. There’s also a checkbox for Automatic Login. If you will be the only one using this VirtualPC, you can leave this checked on.

On the other hand, if you will be sharing this VPC with friends, you may wish to uncheck this. When you do so openSUSE will request you to login each time. One last note, you will want to make your password different from the one you entered for the root user. It’s not a requirement, but it is a good idea. Once you have entered everything, click Next.

[openSUSE 21]


OK, now sit back and wait a few minutes, as openSUSE is going to finish setting up your user account, then is going to run some cleanup.

[openSUSE 22]


When the cleanup is done you are automatically shown the release notes. This describes changes and the like since the last version. Take a quick glance, and know that you can always pull these up later if you are in a hurry. Go ahead and click Next when you are done.

[openSUSE 23]


In this last step you are shown your hardware configuration and asked to confirm it’s what you want to use. While it’s examining your config your screen may switch back to a text display, then back to the graphical installer. This is normal behavior, just be aware of it.

When it’s done examining, you’ll be ready to click Next. Note one item, there have been some issues with openSUSE not detecting the sound card of Virtual PC 2007. If sound is extremely critical to you, consider sticking with either VPC 2004, or drop back to openSUSE 10.1.

I can wait for the sound issue to get fixed in a later patch, so I’ll be clicking Next at this point.

[openSUSE 24]


You’ve hit the finish line! You installation is complete, all you have to do now is click the Finish button.

[openSUSE 25]


When you do, openSUSE will complete a few tasks, then ‘reboot’ your virtual system. This will take a few minutes, and when done you are logged in and ready to use your openSUSE Virtual PC.

[openSUSE 26]


Click on the “Computer” icon in the lower left, to begin exploring your openSUSE installation.

[openSUSE 27]


To get up and running with openSUSE I’d recommend a good podcast to you called Linux Reality. Chess Griffin is the host, and did a great three part tutorial on openSUSE at these links:

Part 1: http://www.linuxreality.com/podcast/episode-16-suse-linux-101-part-1/

Or: http://shrinkster.com/lxh

Part2: http://www.linuxreality.com/podcast/episode-17-suse-linux-101-part-2/

Or: http://shrinkster.com/lxi

Part 3: http://www.linuxreality.com/podcast/episode-18-suse-linux-101-part-3/

Or: http://shrinkster.com/lxj

His original tutorial was for 10.1, so there may be a few minor differences but not enough to make a difference.

There’s also a support site for SUSE Linux you can find at http://wiki.suselinuxsupport.de/wikka.php?wakka=SuSELinuxSupport or http://shrinkster.com/lxk.

That’s about it, one final note. As I tell my kids, when you are done playing make sure to put away your toys. To shut down your Virtual PC openSUSE, just select Logout from the Computer menu, and it will give you a screen with the standard Logout, Shutdown, etc. menu options. Just pick Shutdown and you are free to go get that cup of coffee you’ve been waiting for.

IEnumerator in C#

In yesterday’s post I mentioned the IEnumerator interface. To be honest it probably was not the best example to cite for an interface, since it is implemented in a non-standard fashion. However, it’s also the interface you will probably want to implement the most often, so I thought it worth showing you a quick example.

For today’s lesson I will continue to use the Employee example I’ve shown over the last few days. The only change I need to make is to the Employee’s class declaration, for easy coding I want it to have a public scope. In looking back I hadn’t put a scope qualifier on the class declaration, and when you omit a scope the compiler defaults to internal.

  public class Employee : IPersonM, IPersonP

 

Now that’s done, let’s create a class that will hold multiple employees. We’ll call it Employees (plural) and have a method to add employees to it. Internally we’ll store the individual Employee objects in a generic List<T> collection.

 

using System;

using System.Collections.Generic;

using System.Text;

 

namespace OOPDemo

{

  public class Employees

  {

    private List<Employee> _employees = new List<Employee>();

 

    public void AddEmployee(Employee emp)

    {

      _employees.Add(emp);

    }

 

    public IEnumerator<Employee> GetEnumerator()

    {

      foreach (Employee emp in _employees)

      {

        yield return emp;

      }

    }

 

  }

}

 

Before I explain the details, let’s look at how to use the new collection.

 

      Employees myEmployees = new Employees();

 

      Employee emp1 = new Employee();

      emp1.FirstName = “Carl”;

      emp1.Lastname = “Franklin”;

      myEmployees.AddEmployee(emp1);

 

      Employee emp2 = new Employee();

      emp2.FirstName = “Richard”;

      emp2.Lastname = “Campbell”;

      myEmployees.AddEmployee(emp2);

 

      Employee emp3 = new Employee();

      emp3.FirstName = “Mark”;

      emp3.Lastname = “Miller”;

      myEmployees.AddEmployee(emp3);

 

      string everyone = “”;

      foreach (Employee emp in myEmployees)

      {

        everyone += (emp.FullName() + Environment.NewLine);

      }

 

      MessageBox.Show(everyone, “Everyone”);

 

As you can see this is pretty straight forward, it created 3 employee objects and called the AddEmployee method to add them to our collection. The code then enters a foreach loop retrieving each individual Employee object from the collection of Employees.

What makes this work is the IEnumerator interface. By having the Employees class have a GetEnumerator method that returns an IEnumerator, we enable it to be used anywhere that an IEnumerator can be used, such as a foreach loop.

The only other thing to explain would be the new keyword yield. Each time through the loop the yield will exit the loop and return to the calling routine. The next time through the foreach loop, the GetEnumerator picks right back up at the yield statement, and loops to the next item in our internal List.

To your method, he yield keyword is sort of like sleep mode is to the computer. It pauses, then returns control to the calling routine. When you return, you re-enter the routine right where you left off, with all the routines and variables just as you left them. Not unlike powering up your computer again from sleep mode.

What makes this a little different is that the method GetEnumerator is what implements the IEnumerator interface. Normally, interfaces are implemented by the entire class, not just a single method.

While not the best example of a standard interface, it does demonstrate the power of extending an existing .Net interface. In this example it suddenly allowed your class to be used by a foreach loop. Take advantage of the built in .Net interfaces to make your own classes even more powerful and fit into the .Net environment.

More OOP: Interfaces in C#, Part 2

Yesterday I introduced you to Interfaces in C#. There’s a bit more about interfaces I wanted to share. With a normal class, it can only inherit from one base class. However, it can implement multiple interfaces.

By the way, this seems like a good time for a little lesson in terminology. A class inherits from another class, but it implements one or more interfaces.

Let’s look at our IPerson interface from yesterday. For various reasons our architect has decided it should actually be implemented as two interfaces, one with the properties and another with the method. (For demo purposes I left both interfaces in the same file, in real life I would have each in it’s own file.)

using System;

using System.Collections.Generic;

using System.Text;

 

namespace OOPDemo

{

  public interface IPersonP

  {

    string FirstName { get; set;}

    string Lastname { get; set;}

  }

 

  public interface IPersonM

  {

    string FullName();

  }

 

}

 

Now we need to modify our Employee class to implement both methods.

 

  class Employee : IPersonP, IPersonM

 

Notice all it took was separating the interface names with commas. If we were also inheriting from a base class, we would list it first. Yes, you can both inherit from a single base and implement one or more interfaces for a class.

Finally, we need to make a quick update to our ShowName, since the old IPerson has been replaced with an M and P version:  

    private void ShowName(IPersonM per)

    {

      MessageBox.Show(per.FullName(), “ShowName Method”);

    }

 

You need to be careful when designing your interfaces, not to get too focused. In the above example, what if in the ShowName method you need to also access the FirstName property? Can’t do it with the code as it is now since IPersonM knows nothing about those properties. Instead you’d have to pass in an Employee, in which case we’ve limited our functionality. The ShowName would no longer be able to accept a Contractor or Vendor (assuming we ever created them).

So, we know that a good time to use an interface is when you have a base set of properties and methods, but not code, that you wish to share among classes so that you can treat them as the same generic type. What other times might you wish to use interfaces?

In his book Programming .Net Components (http://shrinkster.com/ly6) Juval Lowy has an entire chapter devoted to interface based programming. When writing a class library (i.e. a dll) Mr. Lowy suggests only exposing interfaces. Why? This leaves you totally free to redesign even your base classes.

Even further, Juval advocates placing all of your interfaces into their own class library. Because it’s fairly quick to create interfaces, it allows both the user interface team and the class library team to get to work, both referencing the same interface dll.

A final reason for using interfaces is to extend your class so that it is compatible with items in the .Net Framework. .Net exposes a slew of interface types, and you can implement any of them in your classes.

A common example is the IEnumerator interface. If you were to implement the IEnumerator interface in your class, you could then use your class anywhere you would use an enumerator in .Net, such as in a foreach construct.

Hopefully by now you’ve seen the power of an interface, and will begin using them in your own applications.

More OOP: Interfaces in C#, Part 1

During our discussion on OOP (see my posts for the last few days) one of the key concepts was the base class. The base class was a place where we could put code that would in turn be used by the classes that descend from the base.

The use of the base class allows us to take advantage of polymorphism, the ability to treat a lot of specific child classes as if they were the same less specific, more generic type (the base). Notice a point I made a moment ago. The base class contains code, that will be inherited.

What if you have a situation where you want a common base, but you don’t have any code that will be reusable by it’s descendants? Interfaces step in to fill the need.

One classic example given in every book is the Shape. You never have “a shape”, instead you have rectangles, squares, circles, triangles and more.

An example from the real world might be the concept of lunch. Every day my coworkers and I go out for lunch. Lunch has a common method called Eat, yet the implementation varies depending on the type of food we pick. With Mexican we can eat chips and tacos with our hands. For Oriental we use chopsticks. For Italian, better use that fork. We have the common concept of Eat, but the implementation for each food type is so different we probably won’t be able to share any code.

Implementing an interface in C# is not difficult. Drawing back on our Employee example from the last few days, let’s say in your company you wanted to define a new type called “Person”. You will never have a “Person” object, instead you will always create an Employee, Contractor, Volunteer, and the like. To implement this, let’s create a Person interface.

First, right click on your solution and select Add, New Item, and select Interface from the long list. Set the scope to public.  

using System;

using System.Collections.Generic;

using System.Text;

 

namespace OOPDemo

{

  public interface IPerson

  {

    string FirstName { get; set;}

    string Lastname { get; set;}

    string FullName();

  }

}

 

There’s several areas I need to draw your attention to. First, after public we used the keyword interface. This is the signal to the compiler that this is a declarations only, and has no code.

Next is the name, you see I put the letter I in front of Person. A long standing tradition is to name all of your interfaces with the letter I in front, and it’s a tradition I’d suggest you stick to.

Notice the FirstName and Lastname areas, this is how we declare there will be properties with a get and set. The FullName line is how we specify there will be a method with the name FullName. Note too there is no scope qualifier in front of any of the return types (in this case they are all string). Because this is an interface, all items must have a pubic scope.

Now we need to actually use the interface. Let’s modify our Employee class to implement the Iperson interface. All it takes is a modification to our class declaration.

  class Employee : IPerson

 

Indicating the Employee class will now implement the Iperson interface carries certain connotations. It means we must implement all of the properties and methods the Iperson interface declares. Since we already have FirstName, Lastname, and FullName we are in good shape. However, if we had not we would have to create those properties or methods we were missing.

Now, via polymorphism we can treat the Iperson just as if it were a base class. Let’s modify the ShowName method from yesterday to use an interface instead of a base class.  

    private void ShowName(IPerson per)

    {

      MessageBox.Show(per.FullName(), “ShowName Method”);

    }

 

This now makes the ShowName more functional for us. In the future, if we do implement a Volunteer or Contractor they too could be used in the ShowName method.

Using interfaces will allow you to further extend the power of polymorphism. In addition it gives you a way to create base classes in situations where you have no common code to put in the base.

Tomorrow: More on Interfaces.

 

Object Oriented Programming Pillar #3: Polymorphism

The third plank of OOP is a concept called Polymorphism. In my last post we went over Inheritance. Inheritance allows us to go from something generic, like an Employee, to something more specific, like a Manager or Peon. Polymorphism allows us to go in the reverse direction, treating something specific as something more generic.

Why would you want to do this? In our example, payroll would be a perfect example. Let’s first create our Peon class. We’ll also be using the Manager and Employee classes we have been using over the last few days.  

using System;

using System.Collections.Generic;

using System.Text;

 

namespace OOPDemo

{

  class Peon : Employee

  {

    public Peon(): base()

    {

    }

 

    public override string FullName()

    {

      string retval;

 

      if (base.FirstName.Length > 0)

        retval = base.FirstName.Substring(0, 1) + “. “ + base.Lastname;

      else

        retval = base.FirstName + ” “ + base.Lastname;

 

      return retval;

    }

  }

}

 

As you can see, Peon is pretty simple, I called the base constructor so I wouldn’t wind up homeless (see yesterday’s comments) and overrode the FullName method just because I could.

Now what we want is a routine that will call a method common to every Employee object. Here’s one I whipped up.  

    private void ShowName(Employee emp)

    {

      MessageBox.Show(emp.FullName(), “ShowName Method”);

    }

 

In the real world, we would probably be doing something here like call a “PayEmployee” method. PayEmployee is something we would do for all employees, regardless of whether they are a manager or a peon. For this example I’m just calling the FullName method, since we’ve been using it the last few days. Now we need to create our various objects and pass them to ShowName.

 

      Employee emp1 = new Employee();

      emp1.FirstName = “Carl”;

      emp1.Lastname = “Franklin”;

      this.ShowName(emp1);

 

      Manager mgr1 = new Manager(); 

      mgr1.FirstName = “Richard”;

      mgr1.Lastname = “Campbell”;

      this.ShowName(mgr1);

 

      Peon peon1 = new Peon();

      peon1.FirstName = “Mark”;

      peon1.Lastname = “Miller”;

      this.ShowName(peon1);

 

Here you can see I’ve created one Employee, one Manager, and one Peon object. But I can pass all three of them to the same ShowName method and treat them like Employees. Why? Because they are all descended from (or are) the Employee class. Polymorphism makes all this work.

You should note something very important here. If you actually run the program, you’ll see the following message boxes appear, in this order:

[Pic of Employee FullName]

ShowName with Employee

[Pic of Manager FullName]

ShowName with Manager

[Pic of Peon FullName]

ShowName with Peon

 

Do you see it? Even though within the ShowName method we are treating everything like an Employee, the compiler was smart enough to know they were not all Employees. Instead, it called the overridden method in the child class (Manager and Peon), not the one in the base class. This behavior is very important to understand. On one hand, it’s what makes Polymorphism so powerful, but if you are not expecting it, you can get bit.

Because this can get confusing, let’s see if I can relate this to a real world example. I have a wife and two daughters. Their base class might be “family member”, but their specific classes are wife (Ammie), daughter 1 (Raven) and daughter 2 (Anna).

On days where I might work from home, I can send family member a message (i.e. yell) “get daddy a Jolt cola”. The base implementation is open refrigerator, get soda, bring to daddy (that’s me). My wife Ammie just uses the base implementation of the “get daddy a Jolt cola” method.

My oldest daughter, Raven isn’t quite tall enough to reach the sodas on the top shelf, so she has to override the “get daddy a Jolt cola” method by adding a step to stand on a stool so she can reach them.

My youngest daughter, Anna is even shorter still, so her override calls for her to stand in a chair in order to reach the soda.

Now, in all three cases I simply call the “get daddy a Jolt cola” method of the “family member” object. When the individual object (Ammie, Raven or Anna) executes the “get daddy a Jolt cola” method, they each use their individual implementation to do so.

So where are some situations where Polymorphism would come in handy? Yesterday you may recall I said my classes in my Database Layer (often referred to as the DL) all descend from a common base class.

Within my program then, I can take all of my database objects and pass them into a “CloseConnection” method. The CloseConnection method does what it says, closes any database connections before exiting the program. Because of Polymorphism, it doesn’t matter what type of data object I’m dealing with (Purchase Order, Employee, Work Order, etc) they all need to close, and this lets me do it in an easy, consistent manner that’s easy to update and maintain.

Another real world example: I created a special combo box control to which I added some additional features. My new combo was descended from the standard combo box in the toolbox.

I then turned around and created four new combo boxes from my special base class combo. Each one was bound to a specific type of data, and I used these over and over in my application. Each one though had some common methods, such as Load and Reset.

When my form loaded, I passed each combo box to a method to load them. All this method did was called the load method for each box, and because I’d overridden the load method it called the correct Load for each type of combo box.

Over the last few days I’ve written on the basics behind Object Oriented Programming, using C# to demonstrate. You should understand I’ve only scratched the service as far as power and flexibility go, OOP is a big subject. But hopefully what I’ve discussed here will serve as a starting point for your OOP journey.