Immutability Through Interfaces in C#

In C#, immutability is a useful concept. It is easy to image a collection that, under some circumstances, should act as an immutable type – take for example a custom method that is designed to print collection’s values after some fancy formatting. Such a method should deal with the collection in a read-only manner. Also, I think it is a good programming practice to provide users with the ability for a class to be passed around and treated as an immutable entity, if the user of the class has a need to do so.

The perils of using reference types is that a complex external method may accidentally modify the object that is passed to it. There are several methods for safeguarding against this. For example, you may want to store a separate copy of the original object and ensure it is unchanged after some method call. Alternatively, you can define two version of the same object, one for use as a constant, and one for use as a writable object. There is also a way to achieve this through the use of interfaces. This idea is not mine, and I first read about in “Accelerated C# 2008”, 2nd edition.

Ok, so the concept is simple. Define three interfaces, where one of them declares the methods for read-only actions; another interfaces declares methods for writable-actions only; and finally, the last interface combines the two. The class for which the controlled immutability is desired, would implement the combined interface. The users of the class would have a choice of, firstly, how to use it themselves (as they can restrict their own access), and secondly, how to pass it to some methods. Note that the methods would need to explicitly accept the object as the ‘agreed by design’ interface type.

In my simple example below I would like to have a control over who has the ability to add items to a generic collection. I do this via making GenericCollection to implement IMaintainable interface, which derives from IImutable and IModifiable.

using System;
using System.Collections.Generic;

namespace ImmutabilityThroughInterfaces
{
    public interface IImmutable<T>
    {
        T GetItem(int p);
        int CollectionSize();
    }

    public interface IModifiable<T>
    {
        void AddItem(T t, int p);
    }

    public interface IMaintainable<T> : IModifiable<T>, IImmutable<T> { }

    public sealed class GenericCollection<T> : IMaintainable<T>
    {
        public GenericCollection(int size)
        {
            Collection = new T[size];
        }

        public void AddItem(T t, int p)
        {
            if (p>=0 && p < Collection.Length)
              Collection[p] = t;
        }

        public T GetItem(int p)
        {
            if (p >= 0 && p < Collection.Length)
                return Collection[p];
            else
                return default(T);
        }

        public IEnumerator<T> GetEnumerator()
        {
            foreach (T item in Collection)
                yield return item;
        }

        public int CollectionSize()
        {
            return Collection.Length;
        }

        private T[] Collection;
    }
}

The Main method shows a rather simplified use example. Notice that NoAttemptToModify method accepts IImmutable collection. Inside this method, it is not possible to call AddItem, so this method is read-only with respect to the collection.

namespace UseExample
{
    using ImmutabilityThroughInterfaces;
    class EntryPoint
    {
        static void Main(string[] args)
        {

            GenericCollection<int> intColl = new GenericCollection<int>(3);
            intColl.AddItem(1, 0);
            intColl.AddItem(2, 1);
            intColl.AddItem(3, 2);

            var immutableCollection = intColl as IImmutable<int>;
            var maintainableCollection = intColl as IMaintainable<int>;

            AttemptToModify(maintainableCollection, 2);
            NoAttemptToModify(immutableCollection, 1);

            Console.ReadLine();
        }

            public static void AttemptToModify(IMaintainable<int> collection, int pos)
           {
                collection.AddItem(5, pos);
           }

            public static void NoAttemptToModify(IImmutable<int> collection, int pos)
            {
                  collection.GetItem(pos);
            }
    }
}

In this post I gave an example of a simple, but rather elegant way to ensure controlled immutability for custom types.

Object.Equals

I have been reading a chapter on C# canonical forms in “Accelerated C# 2008” by Trey Nash when I came across a piece of code that puzzled me. The book is an excellent resource on the language and I can recommend it to everyone, even the more seasoned C# developers.

So, the code I am referring to is on overriding Object.Equals method for reference types. You can find it in chapter 13 on page 386 of the 2nd edition. I am not allowed to reproduce the whole program here, but I will highlight the lines of code that confused me. The code is an example of how to override Object.Equals for a reference type variable when you need the value type semantics. The author provides the override with the following signature:

 
public override bool Equals(object obj)
{
   ...
}

In addition, the example has a static definition for == operator. The passed parameters are of the class type the method is defined in:

public  static bool operator==(ComplexNumber me, ComplexNumber other)
{
    return Equals(me, other);
}

In the Main, two instanced of the ComplexNumber class are declared, both, with the same argument values. The test for equality is the invoked as:

System.Console.WriteLine("Results of Equality is {0}", referenceA == referenceB);

Ok, the above line of code will call the static method operator==, which in turn calls Equals(me,other). So, who calls Equals(object obj)? As I was reading this, I said to myself that there was no way this would compile as there is clearly a mistake in the number of parameters in the Equals call inside operator==. This bothered me since all other code examples in the book were ‘compileable’, at least in my head. So, I went to my desktop PC and typed-up the example, fully expecting it to fail. But it did not. It compiled and ran as expected. I added debug points to see which method is called after Equals(me, other). To my surprise – the Equals(object obj) was called! But it did not make any sense at all…

I was beginning to suspect some ‘implicit substitution’ with this voodoo magic, when I decided to look at the trusty IL in ILDASM. This is what I saw for op_Equality:

Figure 1

Aha! I am not crazy, because clearly the call is to Equals(object,object), not to Equals(object). So, how does a call to Equals(object,object) resolves to a call to Equals(object)? How?!

I was able to find the answer on the MSDN website. Object.Equals(Object,Object) is a static method, so, it cannot be overridden. The answer to my puzzle lies in the Remarks section, where we find this line:

  • If the two objects do not represent the same object reference and neither is null, it calls objA.Equals(objB) and returns the result. This means that if objA overrides the Object.Equals(Object) method, this override is called.

This is what was going on!

A Better Way to Define Generic Collections

Greetings to my blog readers!

Today I am feeling greedy. I want to create a collection class and I want it to do many-many things, including dancing and singing. I want it all! I want to be able to add items of any type to my collection. Thus, it has to be a generic collection, but I want it to be type-safe. I also want it to have iteration capability, so that I can access any value. Also, I want to have some removal functionality. And yes, I want it to dance and sing. Let’s code it up.
 
Below is my coveted collection class. Nice, huh?
 

public sealed class MyCollection<T>
{
        public MyCollection(int s)
        {
            if (s>=0)
              this.storage = new T[s];
        }

        public int MySize()
        {
            return storage.Length;
        }

        public void AddValueAt(T addItem, int pos)
        {
            if (pos<MySize())
               storage[pos] = addItem;
        }

        public T GetValueAt(int i)
        {
            if (i < MySize())
                return storage[i];
            else
                return default(T);
        }

        public void RemoveValueAt(int pos)
        {
            if (pos < MySize())
            {
                IEnumerable<T> query = storage.Where((value, index) => index != pos).ToArray();
                this.storage = new T[MySize() - 1];
                int newPos = 0;
                foreach (T q in query)
                {
                    this.AddValueAt(q, newPos);
                    newPos++;
                }
            }
        }

        public IEnumerator<T> GetEnumerator()
        {
            foreach (T item in storage)
                yield return item;
        }

        public void SingAndDance()
        {
          Console.WriteLine("Singing and dancing!");
        }
        private T[] storage;
}

MyCollection is a generic collection, meaning it can be used to store items of any type. I can create MyCollection of integers, strings, or even objects. The class has the required functionality to add new values to the ‘storage’ array, remove a value at some position, and I even override GetEnumerator() to allow users of MyCollection to use foreach loop.
 
As much as I like MyCollection, there is quite a bit that is wrong with it. Firstly, it is far from being a robust little collection. Even though I check for positions to be below the allocated array size, a line if code that says something like this will compile:


myColl.AddValueAt(2, -1);

Of course, I will get System.IndexOutOfRangeException at run time, but it would have been nice to catch little bugs like this at compile time. Also, my RemoveValueAt() is, at best, inefficient. Finally, I had to type all these lines of code just to have MyCollection class to carry out the basic functionality, and of course, to sing and dance too. There must be a better way to create collection classes in a rich programming language like C#. And there is a better way, and it involves inheritance. To be more specific, one should always make a custom collection class derive from System.Collections.ObjectModel.Collection. Doing so will provide loads of functionality to the custom collection for free, including: Add, Remove, RemoveAt, Clear, IndexOf, and many more. Take a look at the modified MyCollection class:

public sealed class MyCollection<T> : System.Collections.ObjectModel.Collection<T>
{
        public void SingAndDance()
        {
          Console.WriteLine("Singing and dancing!");
        }
}

And that is it. All other functionality, like AddValueAt, RemoveValueAt, MySize and even the GetEnumerator is provided by the base class (albeit under slightly different method names). Although, the attempt to remove an item at a negative index would still compile.
 
To conclude, the moral of this post is – reuse, reuse, reuse. Also, check-out this nice set of blog posts on collections and generics.

Short Tutorial on Delegates and Events

This post is a short tutorial on delegates and events. First, I will describe what delegates and events are, and what they can be used for. Then, I will give a simple example code using a delegate and an event. I will finish by criticising my own example with comments on what and how can be improved.

Let’s start!

In C#, a delegate is a sealed class that derives from System.MulticastDelegate, which is an abstract class that provides some useful functionality. This useful functionality includes binding a delegate to a method or a list of methods, as well as obtaining the list of methods a delegate can invoke once it was bound to them; removing methods from the delegate list, and also returning basic information about the methods a delegate can invoke. When you declare a delegate, the compiler creates the mentioned sealed class for you. It also creates a constructor and three methods for invoking the bound method/s synchronously or asynchronously.  An event is also a delegate, a special one, and it is always declared as an instance of an existing delegate type with a keyword event. I know that this sounds confusing, so, let me show you what I mean:

 

public delegate void EventHandler();    //delegate
public event EventHandler EnteredEight; //event on a delegate


In the above, I declare a delegate EventHandler and an event instance of type EventHandler, called  EnteredEight . The two are now bound together.

Ok, so what can we do with this delegate and event? We can bind a method to the EventHandler and define a process that triggers the EnteredEight event. If you are thinking that my variable names are a bit crazy, let me say that I am doing this to customize the explanation to the example below, where I define a process that fires EnteredEight event when a user enters number ‘8’ on a keyboard (note: for a more useful example of using delegates, check out this post on numerical integration).

 

using System.Collections;
namespace DelegatesAndEvents
{
   public class ListWithEightEvent : ArrayList
   {
      public delegate void EventHandler();    //delegate type
      public event EventHandler EnteredEight; //event on a delegate
      // invoke event after an addition of an 8
      //process that fires the event
      public override int Add(object value)
      {
         int i = base.Add(value);
         if (EnteredEight != null && value.ToString()=="8")
             EnteredEight(); //envoking the event
         return i;
      }
    }

    class Test
    {
       public static void Main()
       {
         ListWithEightEvent list = new ListWithEightEvent(); //class instantiation
         //registering event with the delegate bound to AddedEight method
         list.EnteredEight += new ListWithEightEvent.EventHandler(AddedEight);
         string input;
         Console.WriteLine("Keep entering numbers. Enter 'x' to stop.");
         do{
             input = Console.ReadLine();
             list.Add(input);
         }while(input!="x");
        }
        
        // This will be called whenever the list receives an 8
        public static void AddedEight()
        {
           Console.WriteLine("You have entered an 8!");
        }
     }
}


An example output of this program is shown below:

DelegateandEventExample

 

I have to give credit to the MSDN tutorial for the above code which I stripped off all the extra bits and changed a little to expose the basic delegate-event functionality. Let’s step through the code to work out what is happening. First, I declare a public delegate EventHandler and an event on this delegate, called EnteredEight. I then override the Add method to not only add the user-entered value to the ArrayList, but also to invoke the EnteredEight event if a user presses ‘8’. This is achieved through the AddedEight method that simply writes a line to the console to acknowledge that a number ‘8’ has been entered. In the Main method I instantiate my class and register my event with the delegate, which is bound to the AddedEight method. C# provides ‘+=’ operator to allow an easy way of registering events with delegates bound to some method/s. It is useful to know that the compiler expands this operator to event’s internally defined add_XXX method, which becomes

add_EnteredEight(class DelegatesAndEvents.ListWithEightEvent/EventHandler) in my example.

This tutorial’s example is trivial, and one can do without delegates and events to achieve the same functionality. Also, this example omits several important points about delegates and events. For example, the signature of the delegate must match the signature of the method it is bound to (here, the return type is included in the ‘signature’ meaning). In my example, the signature is “accepts no parameters and returns no parameters”. If I were to change AddedEight to receive or return a value, I would also need to change the delegate declaration. Also, we could have achieved the same functionality with delegates but no events. This is because EventHandler is just a delegate type. Instead of instantiating an event type delegate, I could have directly created non-event EventHandler delegate instance and bound it to a method. The beauty of using events is that the ListWithEightEvent class does not need to have variable of type delegate EventHandler, which would need to be private to protect its integrity. When using events, the compiler creates the delegate member variable for us and always declares it as private.

Can you think of what would happen if I registered Main() with the delegate? A truly bizarre thing happens and I urge you to try it out and examine the program’s stack!

Comparing two stream writers

In this post I will compare two popular stream writers that C# offers: System.IO.FileStream and System.IO.StreamWriter. Here I only concentrate on stream writers, since one can assume that similar properties apply to the stream readers. Also, in this post I discuss file streaming only. There are several other stream types out there, for example network streams or memory streams. I will not discuss them in this post. Perhaps sometimes later…

I don’t know about you, reader, but whenever I have to read or write from a file I pause and think “So, how does one read from a file? What is the syntax, again?” I then proceed by doing a quick google search to remind myself of the syntax. If I am lucky, I quickly locate an easy example, plug-in my own file name and read/write attributes and carry on without pausing to think about the difference between all these ways one can deal with a file stream. Well, this was all about to change once I decided to educate myself properly, and spread the knowledge along the way.

At the top of the System.IO namespace, one can find two abstract classes: System.IO.Stream and System.IO.TextWriter. It is from these abstract classes that System.IO.FileStream and

System.IO.StreamWriter derive respectively. Both classes support synchronous and asynchronous writing. Also, both classes support buffered streaming. Practically speaking, the main difference between the abstract classes is the type of streams they have been designed to support. FileStream supports a more primitive stream of raw byte data, and to make it useful one needs to convert the textual data to bytes that FileStream can operate on. Note that NetworkStream and MemoryStream too operate on raw byte data. StreamWriter, on the other hand, can be used directly with text-based data, such as strings. Take a look at the example code below. In the main method on line 13 I convert the string value to an array of bytes, which is then passed to an instance of FileStream to write to a file. As a counter example, on line 21 I use an instance of StreamWriter to write the string value to a file, without any conversion. At a high level, this is the only practical difference between FileStream and StreamWriter.


using System.IO;

namespace FunWithStreams
{
 class StreamExample
 {
  static void Main(string[] args)
  {
   long position;
   using (FileStream fs = File.Open("examplefile.txt",FileMode.Append))
   {
    string fileText = "This text will be written to a file.";
    byte[] byteText = Encoding.Default.GetBytes(fileText);
    fs.Write(byteText, 0, byteText.Length);
    position = fs.Position;
   }

   using (StreamWriter sw = new StreamWriter("examplefile.txt", true))
   {
    string fileText = "\r\nThis text will also be written to a file.";
    sw.Write(fileText, position+10);
   }
  }
 }
}

Please note that in the above example I am relying on the compiler to call the Dispose for me to effectively close the streams fs and sw. This is the advantage of using the using(){} syntactic sugar statement.

There are two more, lower level differences worth writing about. These are listed below:

  • FileStream supports random file access (using Seek method), while StreamWriter does not.
  • In the MSDN documentation one can read about the Filestream’s position detection capability. The FileStream object routinely checks on methods that access its cached buffer to assure that the operating system’s handle position is the same as its own cached position. If it detects a change in the handle positions during writing, the contents of the buffer are discarded and an IOException exception is thrown.

I hope you’ve enjoyed this quick post on FileStream and StreamWriter. Please take a look at this article on CodeGuru website written by Richard Grimes for more insight into Streams.