Remember me? I’m your old C++ code…

Just recently I was called upon to fix some code that I had written while working as a consultant “way back” in 1998. It’s not that long ago really, but a lifetime in software developer years. At the time I was fresh out of university so this was my first proper assignment as a professional. I was the sole developer on this project and the code was written in C++ using the Lotus Notes/Domino C++ API. This was kind of the norm back then.

In essence this old code was broken in to four programs. They were all server based batch type jobs, run at scheduled intervals. Their common goal was to maintain the people groups in the Lotus Notes Name & Address book to reflect the structure of the organization (which was, and still is, a large organization). That means creating new groups, removing empty groups and adding/moving group members to and from groups. For a user to gain access to the Lotus Domino servers (for mail and other databases) you had to be a member of a group in the hierarchy, since only the top node (and thereby it’s children) was granted access to the servers. The groups were also used as mailing groups to parts of the organization. It would be kind of “critical” for a user if the program made a mistake and it goes without saying that with so much application business logic you wouldn’t choose C++ for this type of task today.

I was amazed that these old programs were still running!! Sure, one program had been altered by someone else a few times some years ago, but the remaining three were running just as I last compiled them back in October of 1999. I thought that was kind of fun and also made me a bit proud. Of course, I believe there are two reasons why this code has run unaltered for so long:

  1. It was written properly and there was no need to alter it
  2. Nobody understood the source code and therefore dared not make a change

I choose to believe reason one. I guess that’s a shocker! However, I was actually able to confirm this fact when I started to work with the source code once again after all these years. It was tidy and easy to read, although I was amazed just how much of the C++ syntax was now strange to me after many years of programming Java, Python and C#. I would not have made all the same choices that I did back then regarding the architecture, but in general I was kind of impressed. There was also valid documentation, written by me, which I found very useful when trying to get back in to the problem mindset. Not bad!! 🙂

It was strange to use Visual C++ 6.0 again which was the IDE/compiler I worked with originally. I did actually try to upgrade the project to Visual Studio 2008, but the Visual Studio C++ compiler wouldn’t compile the original source code so in the end I gave up trying. It was never part of the new assignment and the C++ syntax was just too unfamiliar to me. The customer didn’t care so I stuck to VC++ for the time being. Maybe in the future if I get the opportunity again I will give it another attempt.

Of course, it goes without saying that the actual source code – released in 1999 – was lost, but luckily enough I found a copy on a CD-ROM at home, which was a relief. It made the job a lot easier, but I guess it also shoots to bits my reason one (above) a bit 🙂

Advertisements

C# Delegates and Events

Readers of this blog will know that I’m in the process of learning the ins and out of C#. Coming from a Java/C++ background I was have a bit of trouble getting to grips with C# Delegates and Events. None of the examples I looked at really made sense to me. Isn’t this pretty much the same as Interfaces?

I guess the correct answer is both yes and no. I’m pretty sure you can achieve similar results using plain Interfaces, but now after playing around with Delegates and Events, I kind of see where using them might seem like a better approach.

So, how to get started? Let’s look at a simple example. You have a class that you want to enable to call back it’s caller when something happens – an event, in other words. You have a vague idea of what type of information you want to send to the caller when the event occurs. This is where the delegate steps in and should be your first stop:

    public delegate void MyDelegate1(object sender, EventArgs e);

The delegate is usually declared at the same “level” you would an interface or class. The parameters I have used seem to be the C# norm, but based on my experience playing around, this is not necessary. You can send no parameters or more parameters and they can be of any type you want, if any. The return type can also be something other than void, but as we will see below, this makes little sense for most common scenarios. For now, the important thing to notice is the delegate keyword.

So, how to use it? You need to declare an event:

public class Worker
{
    public event MyDelegate1 MyEvent1;

    public void DoIt()
    {
        if (MyEvent1 != null)
        {
            EventArgs e = new EventArgs();
            MyEvent1(this, e);
        }
    }
}

By creating an instance of the Worker class and calling the DoIt() method we trigger the event. Well, nearly. We still need to register an event handler, but more on that in a moment. For now, notice the event’s declaration. Notice the relationship between our event and delegate. Also notice also the signature of the call to MyEvent1() in the method body. It must be identical to the delegate method signature and return type. Anything else will cause a compiler error. You will also notice that we check if the event is null. A NullReferenceException will be thrown if MyEvent1 is null, and we don’t want that. Not all events will have registered handlers.

The code compiles, but nothing happens. We need to register an event handler. Let’s register two of them just to make the point:

public class Runner
{
    public void SomeMethod()
    {
        Worker w = new Worker();
        w.MyEvent1 += new MyDelegate1(RespondToEvent1Alt1);
        w.MyEvent1 += new MyDelegate1(RespondToEvent1Alt2);
        w.DoIt();
    }

    public void RespondToEvent1Alt1(object sender, EventArgs e)
    {
        Console.WriteLine("Responding to event 1, alternative 1");
    }

    public void RespondToEvent1Alt2(object sender, EventArgs e)
    {
        Console.WriteLine("Responding to event 1, alternative 2");
    }
}

We are doing a few things here. We start by registering code handlers for our event. We are registering two methods to respond to the event. Both method handler’s signature must match the delegate signature. When the event is triggered in DoIt(), the methods will be called in the order they are registered.

What happens if we declare a new delegate with a non-void return type and different signature?

    public delegate int MyDelegate2();

This delegate wants any event handlers to return an int when done processing the event. Event handlers receive no parameters from the event. We modify the Worker class to look like this:

public class Worker
{
    public event MyDelegate1 MyEvent1;
    public event MyDelegate2 MyEvent2;

    public void DoIt()
    {
        if (MyEvent1 != null)
        {
            EventArgs e = new EventArgs();
            MyEvent1(this, e);
        }

        if (MyEvent2 != null)
        {
            int x = MyEvent2();
        }
    }
}

The important thing to notice is the return type and parameters of the call to the new delegate. What happens if we also register two handlers for this event?

public class Runner
{
    public void SomeMethod()
    {
        Worker w = new Worker();
        w.MyEvent1 += new MyDelegate1(RespondToEvent1Alt1);
        w.MyEvent1 += new MyDelegate1(RespondToEvent1Alt2);
        w.MyEvent2 += new MyDelegate2(RespondToEvent2Alt1);
        w.MyEvent2 += new MyDelegate2(RespondToEvent2Alt2);
        w.DoIt();
    }

    // skipped RespondToEvent1Alt1() and RespondToEvent1Alt2() here - same as above

    public int RespondToEvent2Alt1()
    {
        Console.WriteLine("Responding to event 2, alternative 1");
        return 24;
    }

    public int RespondToEvent2Alt2()
    {
        Console.WriteLine("Responding to event 2, alternative 2");
        return 42;
    }
}

When the new event triggers in DoIt() it calls the two new event handlers in order as expected. However, the value of the local variable x will be the value of the last event handler called, here that’s 42. Returning a value from a delegate doesn’t make much sense. There is no way of telling how many event handlers will be registered, if any – which is kind of the point.

Maybe there is a way to process the return values after each event handler, but I haven’t seen this mentioned in any of the C# documenation I’ve seen – not that I’ve been looking actively 😉