Week 13: Notes

events

An event is a class member that lets callers register event handlers that will receive notifications. Each event handler is a delegate. When an event is raised (i.e. fires), a notification is sent to each registered event handler. Each notification includes arguments matching the event's delegate type.

Events are useful for implementing the observer pattern, in which one or more observers may want to hear about changes to an object. A common example of this pattern is a model-view architecture, in which the view observes the model and displays the model's data. In such an architecture we want the model to be unaware of the view. Using an event, a view can register to find out when the model has changed, without giving the model specific knowledge of the view class.

Here's an array class including an event that is raised whenever any array element changes:

delegate void Notify(int index, int old, int now);

class WatchableArray {
    int[] a;
  
    public WatchableArray(int n) {
        a = new int[n];
    }
  
    public event Notify? changed;
  
    public int this[int i] {
        get => a[i];

        set {
            int prev = a[i];
            a[i] = value;
            if (changed != null)
                changed(i, prev, a[i]);  // fire the event to notify observers
        }
    }
}

Notice that the event declaration includes a delegate type, and that we can raise an event using method call syntax.

Use the += operator to register a handler with an event. For example, we can create an instance of the WatchableArray class and register an event handler:

  void onChange(int index, int old, int now) {
      WriteLine($"a[{index}] changed from {old} to {now}");
  }
  
  
WatchableArray a = new(5);
a.changed += onChange;

 

If some method later calls

  a[3] = 4;

then the above event handler will run, and will print a message such as

  a[3] changed from 0 to 4

Be warned: if you attempt to raise an event that has no registered handlers, you will get a NullPointerException. In my opinion this is a weakness in the C# event system: if would be nicer if raising such an event did nothing. However, this is how it works. So in the example above, we need to write

if (changed != null)
    changed(i, prev, a[i]);  // fire the event to notify observers

to guard against this condition.

Introduction to GTK

See the following pages, linked from our course home page:

program sizes

Typically we measure a program's size in the number of lines that it contains. The cloc utility is useful for counting lines in any program.

In the lecture we examined various real-world programs to see how large they are, and which languages they are written in. The line counts here were measured by cloc, and don't include blank lines or comments:

As you can see, many programs are larger than you might think. Also, most programs grow continuously over time as developers add more features.

As a rough estimate, a good programmer might write 1,000 lines of code in a month. So a program with 1,000,000 lines of code might take something like 1,000 person-months = 83 person-years of time to write. Probably no single person can understand every line in a program that large.